diff options
author | agl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-01 17:43:46 +0000 |
---|---|---|
committer | agl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-01 17:43:46 +0000 |
commit | 9fd250ca267e0d477b3de557b8e8571eb9a901dd (patch) | |
tree | e76b6510c72fcb6165ca9db3ae777663947c42c7 /third_party/protobuf | |
parent | ff07d758ff3a211d48c592ff9bd3d888b69fc5b9 (diff) | |
download | chromium_src-9fd250ca267e0d477b3de557b8e8571eb9a901dd.zip chromium_src-9fd250ca267e0d477b3de557b8e8571eb9a901dd.tar.gz chromium_src-9fd250ca267e0d477b3de557b8e8571eb9a901dd.tar.bz2 |
third_party/protobuf: update to upstream r371
1) Got an upstream diff 346:371 from svn
2) Pruned files from the diff that we don't have, as well as
descriptor.pb.*
3) Applied and fixed the merge failures.
4) Copied the code (less descriptor.pb.*) back into the svn source.
5) Manually fixed descriptor.pb.* and plugin.pb.* there.
6) Ran ./generate_descriptor_proto.sh and copied the updated files back.
7) Added new source files to the protoc target in protobuf.gyp.
BUG=none
TEST=sync_unit_tests
Review URL: http://codereview.chromium.org/6737030
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@80180 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'third_party/protobuf')
120 files changed, 13871 insertions, 3462 deletions
diff --git a/third_party/protobuf/README.chromium b/third_party/protobuf/README.chromium index 1318d3a..3bfe9cb 100644 --- a/third_party/protobuf/README.chromium +++ b/third_party/protobuf/README.chromium @@ -3,7 +3,7 @@ Short Name: protobuf URL: http://protobuf.googlecode.com/svn/trunk License File: COPYING.txt Version: unknown -Revision: r346 +Revision: r371 Local files (not taken from upstream): README.chromium diff --git a/third_party/protobuf/protobuf.gyp b/third_party/protobuf/protobuf.gyp index bafc344..909c955 100644 --- a/third_party/protobuf/protobuf.gyp +++ b/third_party/protobuf/protobuf.gyp @@ -56,7 +56,6 @@ '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', @@ -211,6 +210,8 @@ 'src/google/protobuf/compiler/java/java_primitive_field.h', 'src/google/protobuf/compiler/java/java_service.cc', 'src/google/protobuf/compiler/java/java_service.h', + 'src/google/protobuf/compiler/java/java_string_field.cc', + 'src/google/protobuf/compiler/java/java_string_field.h', 'src/google/protobuf/compiler/python/python_generator.cc', 'src/google/protobuf/compiler/main.cc', ], diff --git a/third_party/protobuf/python/README.txt b/third_party/protobuf/python/README.txt index 96f1a73..73a2656 100644 --- a/third_party/protobuf/python/README.txt +++ b/third_party/protobuf/python/README.txt @@ -63,6 +63,9 @@ Installation $ python setup.py install This step may require superuser privileges. + NOTE: To use C++ implementation, you need to export the environment variable + before this step. See the "C++ Implementation" section below for more + details. Usage ===== @@ -71,3 +74,24 @@ The complete documentation for Protocol Buffers is available via the web at: http://code.google.com/apis/protocolbuffers/ + +C++ Implementation +================== + +WARNING: This is EXPERIMENTAL and only available for CPython platforms. + +The C++ implementation for Python messages is built as a Python extension to +improve the overall protobuf Python performance. + +To use the C++ implementation, export an environment variable: + + $ export PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=cpp + +You need to export this variable before running setup.py script to build and +install the extension. You must also set the variable at runtime, otherwise +the pure-Python implementation will be used. In a future release, we will +change the default so that C++ implementation is used whenever it is available. +It is strongly recommended to run `python setup.py test` after setting the +variable to "cpp", so the tests will be against C++ implemented Python +messages. + diff --git a/third_party/protobuf/python/ez_setup.py b/third_party/protobuf/python/ez_setup.py index b7a9849..a2cf777 100755 --- a/third_party/protobuf/python/ez_setup.py +++ b/third_party/protobuf/python/ez_setup.py @@ -2,7 +2,7 @@ # This file was obtained from: # http://peak.telecommunity.com/dist/ez_setup.py -# on 2009/4/17. +# on 2011/1/21. """Bootstrap setuptools installation @@ -19,7 +19,7 @@ the appropriate options to ``use_setuptools()``. This file can also be run as a script to install or upgrade setuptools. """ import sys -DEFAULT_VERSION = "0.6c9" +DEFAULT_VERSION = "0.6c11" DEFAULT_URL = "http://pypi.python.org/packages/%s/s/setuptools/" % sys.version[:3] md5_data = { @@ -33,6 +33,14 @@ md5_data = { 'setuptools-0.6b4-py2.4.egg': '4cb2a185d228dacffb2d17f103b3b1c4', 'setuptools-0.6c1-py2.3.egg': 'b3f2b5539d65cb7f74ad79127f1a908c', 'setuptools-0.6c1-py2.4.egg': 'b45adeda0667d2d2ffe14009364f2a4b', + 'setuptools-0.6c10-py2.3.egg': 'ce1e2ab5d3a0256456d9fc13800a7090', + 'setuptools-0.6c10-py2.4.egg': '57d6d9d6e9b80772c59a53a8433a5dd4', + 'setuptools-0.6c10-py2.5.egg': 'de46ac8b1c97c895572e5e8596aeb8c7', + 'setuptools-0.6c10-py2.6.egg': '58ea40aef06da02ce641495523a0b7f5', + 'setuptools-0.6c11-py2.3.egg': '2baeac6e13d414a9d28e7ba5b5a596de', + 'setuptools-0.6c11-py2.4.egg': 'bd639f9b0eac4c42497034dec2ec0c2b', + 'setuptools-0.6c11-py2.5.egg': '64c94f3bf7a72a13ec83e0b24f2749b2', + 'setuptools-0.6c11-py2.6.egg': 'bfa92100bd772d5a213eedd356d64086', 'setuptools-0.6c2-py2.3.egg': 'f0064bf6aa2b7d0f3ba0b43f20817c27', 'setuptools-0.6c2-py2.4.egg': '616192eec35f47e8ea16cd6a122b7277', 'setuptools-0.6c3-py2.3.egg': 'f181fa125dfe85a259c9cd6f1d7b78fa', @@ -109,11 +117,11 @@ def use_setuptools( "\n\n(Currently using %r)" ) % (version, e.args[0]) sys.exit(2) - else: - del pkg_resources, sys.modules['pkg_resources'] # reload ok - return do_download() except pkg_resources.DistributionNotFound: - return do_download() + pass + + del pkg_resources, sys.modules['pkg_resources'] # reload ok + return do_download() def download_setuptools( version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir, @@ -273,9 +281,3 @@ if __name__=='__main__': update_md5(sys.argv[2:]) else: main(sys.argv[1:]) - - - - - - diff --git a/third_party/protobuf/python/google/protobuf/descriptor.py b/third_party/protobuf/python/google/protobuf/descriptor.py index aa4ab96..cf609be 100755 --- a/third_party/protobuf/python/google/protobuf/descriptor.py +++ b/third_party/protobuf/python/google/protobuf/descriptor.py @@ -28,16 +28,6 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# TODO(robinson): We probably need to provide deep-copy methods for -# descriptor types. When a FieldDescriptor is passed into -# Descriptor.__init__(), we should make a deep copy and then set -# containing_type on it. Alternatively, we could just get -# rid of containing_type (iit's not needed for reflection.py, at least). -# -# TODO(robinson): Print method? -# -# TODO(robinson): Useful __repr__? - """Descriptors essentially contain exactly the information found in a .proto file, in types that make this information accessible in Python. """ @@ -45,6 +35,13 @@ file, in types that make this information accessible in Python. __author__ = 'robinson@google.com (Will Robinson)' +from google.protobuf.internal import api_implementation + + +if api_implementation.Type() == 'cpp': + from google.protobuf.internal import cpp_message + + class Error(Exception): """Base error for this module.""" @@ -396,6 +393,13 @@ class FieldDescriptor(DescriptorBase): self.enum_type = enum_type self.is_extension = is_extension self.extension_scope = extension_scope + if api_implementation.Type() == 'cpp': + if is_extension: + self._cdescriptor = cpp_message.GetExtensionDescriptor(full_name) + else: + self._cdescriptor = cpp_message.GetFieldDescriptor(full_name) + else: + self._cdescriptor = None class EnumDescriptor(_NestedDescriptorBase): @@ -567,9 +571,13 @@ class FileDescriptor(DescriptorBase): """Constructor.""" super(FileDescriptor, self).__init__(options, 'FileOptions') + self.message_types_by_name = {} self.name = name self.package = package self.serialized_pb = serialized_pb + if (api_implementation.Type() == 'cpp' and + self.serialized_pb is not None): + cpp_message.BuildFile(self.serialized_pb) def CopyToProto(self, proto): """Copies this to a descriptor_pb2.FileDescriptorProto. diff --git a/third_party/protobuf/python/google/protobuf/internal/api_implementation.py b/third_party/protobuf/python/google/protobuf/internal/api_implementation.py new file mode 100644 index 0000000..b3e412e --- /dev/null +++ b/third_party/protobuf/python/google/protobuf/internal/api_implementation.py @@ -0,0 +1,64 @@ +# 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. + +""" +This module is the central entity that determines which implementation of the +API is used. +""" + +__author__ = 'petar@google.com (Petar Petrov)' + +import os +# This environment variable can be used to switch to a certain implementation +# of the Python API. Right now only 'python' and 'cpp' are valid values. Any +# other value will be ignored. +_implementation_type = os.getenv('PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION', + 'python') + + +if _implementation_type != 'python': + # For now, by default use the pure-Python implementation. + # The code below checks if the C extension is available and + # uses it if it is available. + _implementation_type = 'cpp' + ## Determine automatically which implementation to use. + #try: + # from google.protobuf.internal import cpp_message + # _implementation_type = 'cpp' + #except ImportError, e: + # _implementation_type = 'python' + + +# Usage of this function is discouraged. Clients shouldn't care which +# implementation of the API is in use. Note that there is no guarantee +# that differences between APIs will be maintained. +# Please don't use this function if possible. +def Type(): + return _implementation_type diff --git a/third_party/protobuf/python/google/protobuf/internal/containers.py b/third_party/protobuf/python/google/protobuf/internal/containers.py index 5cc7d6d..097a3c2 100755 --- a/third_party/protobuf/python/google/protobuf/internal/containers.py +++ b/third_party/protobuf/python/google/protobuf/internal/containers.py @@ -72,9 +72,15 @@ class BaseContainer(object): # The concrete classes should define __eq__. return not self == other + def __hash__(self): + raise TypeError('unhashable object') + def __repr__(self): return repr(self._values) + def sort(self, sort_function=cmp): + self._values.sort(sort_function) + class RepeatedScalarFieldContainer(BaseContainer): @@ -198,28 +204,37 @@ class RepeatedCompositeFieldContainer(BaseContainer): super(RepeatedCompositeFieldContainer, self).__init__(message_listener) self._message_descriptor = message_descriptor - def add(self): - new_element = self._message_descriptor._concrete_class() + def add(self, **kwargs): + """Adds a new element at the end of the list and returns it. Keyword + arguments may be used to initialize the element. + """ + new_element = self._message_descriptor._concrete_class(**kwargs) new_element._SetListener(self._message_listener) self._values.append(new_element) if not self._message_listener.dirty: self._message_listener.Modified() return new_element - def MergeFrom(self, other): - """Appends the contents of another repeated field of the same type to this - one, copying each individual message. + def extend(self, elem_seq): + """Extends by appending the given sequence of elements of the same type + as this one, copying each individual message. """ message_class = self._message_descriptor._concrete_class listener = self._message_listener values = self._values - for message in other._values: + for message in elem_seq: new_element = message_class() new_element._SetListener(listener) new_element.MergeFrom(message) values.append(new_element) listener.Modified() + def MergeFrom(self, other): + """Appends the contents of another repeated field of the same type to this + one, copying each individual message. + """ + self.extend(other._values) + def __getslice__(self, start, stop): """Retrieves the subset of items from between the specified indices.""" return self._values[start:stop] diff --git a/third_party/protobuf/python/google/protobuf/internal/cpp_message.py b/third_party/protobuf/python/google/protobuf/internal/cpp_message.py new file mode 100644 index 0000000..3f42650 --- /dev/null +++ b/third_party/protobuf/python/google/protobuf/internal/cpp_message.py @@ -0,0 +1,616 @@ +# 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. + +"""Contains helper functions used to create protocol message classes from +Descriptor objects at runtime backed by the protocol buffer C++ API. +""" + +__author__ = 'petar@google.com (Petar Petrov)' + +import operator +from google.protobuf.internal import _net_proto2___python +from google.protobuf import message + + +_LABEL_REPEATED = _net_proto2___python.LABEL_REPEATED +_LABEL_OPTIONAL = _net_proto2___python.LABEL_OPTIONAL +_CPPTYPE_MESSAGE = _net_proto2___python.CPPTYPE_MESSAGE +_TYPE_MESSAGE = _net_proto2___python.TYPE_MESSAGE + + +def GetDescriptorPool(): + """Creates a new DescriptorPool C++ object.""" + return _net_proto2___python.NewCDescriptorPool() + + +_pool = GetDescriptorPool() + + +def GetFieldDescriptor(full_field_name): + """Searches for a field descriptor given a full field name.""" + return _pool.FindFieldByName(full_field_name) + + +def BuildFile(content): + """Registers a new proto file in the underlying C++ descriptor pool.""" + _net_proto2___python.BuildFile(content) + + +def GetExtensionDescriptor(full_extension_name): + """Searches for extension descriptor given a full field name.""" + return _pool.FindExtensionByName(full_extension_name) + + +def NewCMessage(full_message_name): + """Creates a new C++ protocol message by its name.""" + return _net_proto2___python.NewCMessage(full_message_name) + + +def ScalarProperty(cdescriptor): + """Returns a scalar property for the given descriptor.""" + + def Getter(self): + return self._cmsg.GetScalar(cdescriptor) + + def Setter(self, value): + self._cmsg.SetScalar(cdescriptor, value) + + return property(Getter, Setter) + + +def CompositeProperty(cdescriptor, message_type): + """Returns a Python property the given composite field.""" + + def Getter(self): + sub_message = self._composite_fields.get(cdescriptor.name, None) + if sub_message is None: + cmessage = self._cmsg.NewSubMessage(cdescriptor) + sub_message = message_type._concrete_class(__cmessage=cmessage) + self._composite_fields[cdescriptor.name] = sub_message + return sub_message + + return property(Getter) + + +class RepeatedScalarContainer(object): + """Container for repeated scalar fields.""" + + __slots__ = ['_message', '_cfield_descriptor', '_cmsg'] + + def __init__(self, msg, cfield_descriptor): + self._message = msg + self._cmsg = msg._cmsg + self._cfield_descriptor = cfield_descriptor + + def append(self, value): + self._cmsg.AddRepeatedScalar( + self._cfield_descriptor, value) + + def extend(self, sequence): + for element in sequence: + self.append(element) + + def insert(self, key, value): + values = self[slice(None, None, None)] + values.insert(key, value) + self._cmsg.AssignRepeatedScalar(self._cfield_descriptor, values) + + def remove(self, value): + values = self[slice(None, None, None)] + values.remove(value) + self._cmsg.AssignRepeatedScalar(self._cfield_descriptor, values) + + def __setitem__(self, key, value): + values = self[slice(None, None, None)] + values[key] = value + self._cmsg.AssignRepeatedScalar(self._cfield_descriptor, values) + + def __getitem__(self, key): + return self._cmsg.GetRepeatedScalar(self._cfield_descriptor, key) + + def __delitem__(self, key): + self._cmsg.DeleteRepeatedField(self._cfield_descriptor, key) + + def __len__(self): + return len(self[slice(None, None, None)]) + + def __eq__(self, other): + if self is other: + return True + if not operator.isSequenceType(other): + raise TypeError( + 'Can only compare repeated scalar fields against sequences.') + # We are presumably comparing against some other sequence type. + return other == self[slice(None, None, None)] + + def __ne__(self, other): + return not self == other + + def __hash__(self): + raise TypeError('unhashable object') + + def sort(self, sort_function=cmp): + values = self[slice(None, None, None)] + values.sort(sort_function) + self._cmsg.AssignRepeatedScalar(self._cfield_descriptor, values) + + +def RepeatedScalarProperty(cdescriptor): + """Returns a Python property the given repeated scalar field.""" + + def Getter(self): + container = self._composite_fields.get(cdescriptor.name, None) + if container is None: + container = RepeatedScalarContainer(self, cdescriptor) + self._composite_fields[cdescriptor.name] = container + return container + + def Setter(self, new_value): + raise AttributeError('Assignment not allowed to repeated field ' + '"%s" in protocol message object.' % cdescriptor.name) + + doc = 'Magic attribute generated for "%s" proto field.' % cdescriptor.name + return property(Getter, Setter, doc=doc) + + +class RepeatedCompositeContainer(object): + """Container for repeated composite fields.""" + + __slots__ = ['_message', '_subclass', '_cfield_descriptor', '_cmsg'] + + def __init__(self, msg, cfield_descriptor, subclass): + self._message = msg + self._cmsg = msg._cmsg + self._subclass = subclass + self._cfield_descriptor = cfield_descriptor + + def add(self, **kwargs): + cmessage = self._cmsg.AddMessage(self._cfield_descriptor) + return self._subclass(__cmessage=cmessage, __owner=self._message, **kwargs) + + def extend(self, elem_seq): + """Extends by appending the given sequence of elements of the same type + as this one, copying each individual message. + """ + for message in elem_seq: + self.add().MergeFrom(message) + + def MergeFrom(self, other): + for message in other[:]: + self.add().MergeFrom(message) + + def __getitem__(self, key): + cmessages = self._cmsg.GetRepeatedMessage( + self._cfield_descriptor, key) + subclass = self._subclass + if not isinstance(cmessages, list): + return subclass(__cmessage=cmessages, __owner=self._message) + + return [subclass(__cmessage=m, __owner=self._message) for m in cmessages] + + def __delitem__(self, key): + self._cmsg.DeleteRepeatedField( + self._cfield_descriptor, key) + + def __len__(self): + return self._cmsg.FieldLength(self._cfield_descriptor) + + def __eq__(self, other): + """Compares the current instance with another one.""" + if self is other: + return True + if not isinstance(other, self.__class__): + raise TypeError('Can only compare repeated composite fields against ' + 'other repeated composite fields.') + messages = self[slice(None, None, None)] + other_messages = other[slice(None, None, None)] + return messages == other_messages + + def __hash__(self): + raise TypeError('unhashable object') + + def sort(self, sort_function=cmp): + messages = [] + for index in range(len(self)): + # messages[i][0] is where the i-th element of the new array has to come + # from. + # messages[i][1] is where the i-th element of the old array has to go. + messages.append([index, 0, self[index]]) + messages.sort(lambda x,y: sort_function(x[2], y[2])) + + # Remember which position each elements has to move to. + for i in range(len(messages)): + messages[messages[i][0]][1] = i + + # Apply the transposition. + for i in range(len(messages)): + from_position = messages[i][0] + if i == from_position: + continue + self._cmsg.SwapRepeatedFieldElements( + self._cfield_descriptor, i, from_position) + messages[messages[i][1]][0] = from_position + + +def RepeatedCompositeProperty(cdescriptor, message_type): + """Returns a Python property for the given repeated composite field.""" + + def Getter(self): + container = self._composite_fields.get(cdescriptor.name, None) + if container is None: + container = RepeatedCompositeContainer( + self, cdescriptor, message_type._concrete_class) + self._composite_fields[cdescriptor.name] = container + return container + + def Setter(self, new_value): + raise AttributeError('Assignment not allowed to repeated field ' + '"%s" in protocol message object.' % cdescriptor.name) + + doc = 'Magic attribute generated for "%s" proto field.' % cdescriptor.name + return property(Getter, Setter, doc=doc) + + +class ExtensionDict(object): + """Extension dictionary added to each protocol message.""" + + def __init__(self, msg): + self._message = msg + self._cmsg = msg._cmsg + self._values = {} + + def __setitem__(self, extension, value): + from google.protobuf import descriptor + if not isinstance(extension, descriptor.FieldDescriptor): + raise KeyError('Bad extension %r.' % (extension,)) + cdescriptor = extension._cdescriptor + if (cdescriptor.label != _LABEL_OPTIONAL or + cdescriptor.cpp_type == _CPPTYPE_MESSAGE): + raise TypeError('Extension %r is repeated and/or a composite type.' % ( + extension.full_name,)) + self._cmsg.SetScalar(cdescriptor, value) + self._values[extension] = value + + def __getitem__(self, extension): + from google.protobuf import descriptor + if not isinstance(extension, descriptor.FieldDescriptor): + raise KeyError('Bad extension %r.' % (extension,)) + + cdescriptor = extension._cdescriptor + if (cdescriptor.label != _LABEL_REPEATED and + cdescriptor.cpp_type != _CPPTYPE_MESSAGE): + return self._cmsg.GetScalar(cdescriptor) + + ext = self._values.get(extension, None) + if ext is not None: + return ext + + ext = self._CreateNewHandle(extension) + self._values[extension] = ext + return ext + + def ClearExtension(self, extension): + from google.protobuf import descriptor + if not isinstance(extension, descriptor.FieldDescriptor): + raise KeyError('Bad extension %r.' % (extension,)) + self._cmsg.ClearFieldByDescriptor(extension._cdescriptor) + if extension in self._values: + del self._values[extension] + + def HasExtension(self, extension): + from google.protobuf import descriptor + if not isinstance(extension, descriptor.FieldDescriptor): + raise KeyError('Bad extension %r.' % (extension,)) + return self._cmsg.HasFieldByDescriptor(extension._cdescriptor) + + def _FindExtensionByName(self, name): + """Tries to find a known extension with the specified name. + + Args: + name: Extension full name. + + Returns: + Extension field descriptor. + """ + return self._message._extensions_by_name.get(name, None) + + def _CreateNewHandle(self, extension): + cdescriptor = extension._cdescriptor + if (cdescriptor.label != _LABEL_REPEATED and + cdescriptor.cpp_type == _CPPTYPE_MESSAGE): + cmessage = self._cmsg.NewSubMessage(cdescriptor) + return extension.message_type._concrete_class(__cmessage=cmessage) + + if cdescriptor.label == _LABEL_REPEATED: + if cdescriptor.cpp_type == _CPPTYPE_MESSAGE: + return RepeatedCompositeContainer( + self._message, cdescriptor, extension.message_type._concrete_class) + else: + return RepeatedScalarContainer(self._message, cdescriptor) + # This shouldn't happen! + assert False + return None + + +def NewMessage(message_descriptor, dictionary): + """Creates a new protocol message *class*.""" + _AddClassAttributesForNestedExtensions(message_descriptor, dictionary) + _AddEnumValues(message_descriptor, dictionary) + _AddDescriptors(message_descriptor, dictionary) + + +def InitMessage(message_descriptor, cls): + """Constructs a new message instance (called before instance's __init__).""" + cls._extensions_by_name = {} + _AddInitMethod(message_descriptor, cls) + _AddMessageMethods(message_descriptor, cls) + _AddPropertiesForExtensions(message_descriptor, cls) + + +def _AddDescriptors(message_descriptor, dictionary): + """Sets up a new protocol message class dictionary. + + Args: + message_descriptor: A Descriptor instance describing this message type. + dictionary: Class dictionary to which we'll add a '__slots__' entry. + """ + dictionary['__descriptors'] = {} + for field in message_descriptor.fields: + dictionary['__descriptors'][field.name] = GetFieldDescriptor( + field.full_name) + + dictionary['__slots__'] = list(dictionary['__descriptors'].iterkeys()) + [ + '_cmsg', '_owner', '_composite_fields', 'Extensions'] + + +def _AddEnumValues(message_descriptor, dictionary): + """Sets class-level attributes for all enum fields defined in this message. + + Args: + message_descriptor: Descriptor object for this message type. + dictionary: Class dictionary that should be populated. + """ + for enum_type in message_descriptor.enum_types: + for enum_value in enum_type.values: + dictionary[enum_value.name] = enum_value.number + + +def _AddClassAttributesForNestedExtensions(message_descriptor, dictionary): + """Adds class attributes for the nested extensions.""" + extension_dict = message_descriptor.extensions_by_name + for extension_name, extension_field in extension_dict.iteritems(): + assert extension_name not in dictionary + dictionary[extension_name] = extension_field + + +def _AddInitMethod(message_descriptor, cls): + """Adds an __init__ method to cls.""" + + # Create and attach message field properties to the message class. + # This can be done just once per message class, since property setters and + # getters are passed the message instance. + # This makes message instantiation extremely fast, and at the same time it + # doesn't require the creation of property objects for each message instance, + # which saves a lot of memory. + for field in message_descriptor.fields: + field_cdescriptor = cls.__descriptors[field.name] + if field.label == _LABEL_REPEATED: + if field.cpp_type == _CPPTYPE_MESSAGE: + value = RepeatedCompositeProperty(field_cdescriptor, field.message_type) + else: + value = RepeatedScalarProperty(field_cdescriptor) + elif field.cpp_type == _CPPTYPE_MESSAGE: + value = CompositeProperty(field_cdescriptor, field.message_type) + else: + value = ScalarProperty(field_cdescriptor) + setattr(cls, field.name, value) + + # Attach a constant with the field number. + constant_name = field.name.upper() + '_FIELD_NUMBER' + setattr(cls, constant_name, field.number) + + def Init(self, **kwargs): + """Message constructor.""" + cmessage = kwargs.pop('__cmessage', None) + if cmessage is None: + self._cmsg = NewCMessage(message_descriptor.full_name) + else: + self._cmsg = cmessage + + # Keep a reference to the owner, as the owner keeps a reference to the + # underlying protocol buffer message. + owner = kwargs.pop('__owner', None) + if owner is not None: + self._owner = owner + + self.Extensions = ExtensionDict(self) + self._composite_fields = {} + + for field_name, field_value in kwargs.iteritems(): + field_cdescriptor = self.__descriptors.get(field_name, None) + if field_cdescriptor is None: + raise ValueError('Protocol message has no "%s" field.' % field_name) + if field_cdescriptor.label == _LABEL_REPEATED: + if field_cdescriptor.cpp_type == _CPPTYPE_MESSAGE: + for val in field_value: + getattr(self, field_name).add().MergeFrom(val) + else: + getattr(self, field_name).extend(field_value) + elif field_cdescriptor.cpp_type == _CPPTYPE_MESSAGE: + getattr(self, field_name).MergeFrom(field_value) + else: + setattr(self, field_name, field_value) + + Init.__module__ = None + Init.__doc__ = None + cls.__init__ = Init + + +def _IsMessageSetExtension(field): + """Checks if a field is a message set extension.""" + return (field.is_extension and + field.containing_type.has_options and + field.containing_type.GetOptions().message_set_wire_format and + field.type == _TYPE_MESSAGE and + field.message_type == field.extension_scope and + field.label == _LABEL_OPTIONAL) + + +def _AddMessageMethods(message_descriptor, cls): + """Adds the methods to a protocol message class.""" + if message_descriptor.is_extendable: + + def ClearExtension(self, extension): + self.Extensions.ClearExtension(extension) + + def HasExtension(self, extension): + return self.Extensions.HasExtension(extension) + + def HasField(self, field_name): + return self._cmsg.HasField(field_name) + + def ClearField(self, field_name): + if field_name in self._composite_fields: + del self._composite_fields[field_name] + self._cmsg.ClearField(field_name) + + def Clear(self): + return self._cmsg.Clear() + + def IsInitialized(self, errors=None): + if self._cmsg.IsInitialized(): + return True + if errors is not None: + errors.extend(self.FindInitializationErrors()); + return False + + def SerializeToString(self): + if not self.IsInitialized(): + raise message.EncodeError( + 'Message is missing required fields: ' + + ','.join(self.FindInitializationErrors())) + return self._cmsg.SerializeToString() + + def SerializePartialToString(self): + return self._cmsg.SerializePartialToString() + + def ParseFromString(self, serialized): + self.Clear() + self.MergeFromString(serialized) + + def MergeFromString(self, serialized): + byte_size = self._cmsg.MergeFromString(serialized) + if byte_size < 0: + raise message.DecodeError('Unable to merge from string.') + return byte_size + + def MergeFrom(self, msg): + if not isinstance(msg, cls): + raise TypeError( + "Parameter to MergeFrom() must be instance of same class.") + self._cmsg.MergeFrom(msg._cmsg) + + def CopyFrom(self, msg): + self._cmsg.CopyFrom(msg._cmsg) + + def ByteSize(self): + return self._cmsg.ByteSize() + + def SetInParent(self): + return self._cmsg.SetInParent() + + def ListFields(self): + all_fields = [] + field_list = self._cmsg.ListFields() + fields_by_name = cls.DESCRIPTOR.fields_by_name + for is_extension, field_name in field_list: + if is_extension: + extension = cls._extensions_by_name[field_name] + all_fields.append((extension, self.Extensions[extension])) + else: + field_descriptor = fields_by_name[field_name] + all_fields.append( + (field_descriptor, getattr(self, field_name))) + all_fields.sort(key=lambda item: item[0].number) + return all_fields + + def FindInitializationErrors(self): + return self._cmsg.FindInitializationErrors() + + def __str__(self): + return self._cmsg.DebugString() + + def __eq__(self, other): + if self is other: + return True + if not isinstance(other, self.__class__): + return False + return self.ListFields() == other.ListFields() + + def __ne__(self, other): + return not self == other + + def __hash__(self): + raise TypeError('unhashable object') + + def __unicode__(self): + return text_format.MessageToString(self, as_utf8=True).decode('utf-8') + + # Attach the local methods to the message class. + for key, value in locals().copy().iteritems(): + if key not in ('key', 'value', '__builtins__', '__name__', '__doc__'): + setattr(cls, key, value) + + # Static methods: + + def RegisterExtension(extension_handle): + extension_handle.containing_type = cls.DESCRIPTOR + cls._extensions_by_name[extension_handle.full_name] = extension_handle + + if _IsMessageSetExtension(extension_handle): + # MessageSet extension. Also register under type name. + cls._extensions_by_name[ + extension_handle.message_type.full_name] = extension_handle + cls.RegisterExtension = staticmethod(RegisterExtension) + + def FromString(string): + msg = cls() + msg.MergeFromString(string) + return msg + cls.FromString = staticmethod(FromString) + + + +def _AddPropertiesForExtensions(message_descriptor, cls): + """Adds properties for all fields in this protocol message type.""" + extension_dict = message_descriptor.extensions_by_name + for extension_name, extension_field in extension_dict.iteritems(): + constant_name = extension_name.upper() + '_FIELD_NUMBER' + setattr(cls, constant_name, extension_field.number) diff --git a/third_party/protobuf/python/google/protobuf/internal/decoder.py b/third_party/protobuf/python/google/protobuf/internal/decoder.py index 461a30c..55f746f 100755 --- a/third_party/protobuf/python/google/protobuf/internal/decoder.py +++ b/third_party/protobuf/python/google/protobuf/internal/decoder.py @@ -86,6 +86,13 @@ from google.protobuf.internal import wire_format from google.protobuf import message +# This will overflow and thus become IEEE-754 "infinity". We would use +# "float('inf')" but it doesn't work on Windows pre-Python-2.6. +_POS_INF = 1e10000 +_NEG_INF = -_POS_INF +_NAN = _POS_INF * 0 + + # This is not for optimization, but rather to avoid conflicts with local # variables named "message". _DecodeError = message.DecodeError @@ -269,6 +276,72 @@ def _StructPackDecoder(wire_type, format): return _SimpleDecoder(wire_type, InnerDecode) +def _FloatDecoder(): + """Returns a decoder for a float field. + + This code works around a bug in struct.unpack for non-finite 32-bit + floating-point values. + """ + + local_unpack = struct.unpack + + def InnerDecode(buffer, pos): + # We expect a 32-bit value in little-endian byte order. Bit 1 is the sign + # bit, bits 2-9 represent the exponent, and bits 10-32 are the significand. + new_pos = pos + 4 + float_bytes = buffer[pos:new_pos] + + # If this value has all its exponent bits set, then it's non-finite. + # In Python 2.4, struct.unpack will convert it to a finite 64-bit value. + # To avoid that, we parse it specially. + if ((float_bytes[3] in '\x7F\xFF') + and (float_bytes[2] >= '\x80')): + # If at least one significand bit is set... + if float_bytes[0:3] != '\x00\x00\x80': + return (_NAN, new_pos) + # If sign bit is set... + if float_bytes[3] == '\xFF': + return (_NEG_INF, new_pos) + return (_POS_INF, new_pos) + + # Note that we expect someone up-stack to catch struct.error and convert + # it to _DecodeError -- this way we don't have to set up exception- + # handling blocks every time we parse one value. + result = local_unpack('<f', float_bytes)[0] + return (result, new_pos) + return _SimpleDecoder(wire_format.WIRETYPE_FIXED32, InnerDecode) + + +def _DoubleDecoder(): + """Returns a decoder for a double field. + + This code works around a bug in struct.unpack for not-a-number. + """ + + local_unpack = struct.unpack + + def InnerDecode(buffer, pos): + # We expect a 64-bit value in little-endian byte order. Bit 1 is the sign + # bit, bits 2-12 represent the exponent, and bits 13-64 are the significand. + new_pos = pos + 8 + double_bytes = buffer[pos:new_pos] + + # If this value has all its exponent bits set and at least one significand + # bit set, it's not a number. In Python 2.4, struct.unpack will treat it + # as inf or -inf. To avoid that, we treat it specially. + if ((double_bytes[7] in '\x7F\xFF') + and (double_bytes[6] >= '\xF0') + and (double_bytes[0:7] != '\x00\x00\x00\x00\x00\x00\xF0')): + return (_NAN, new_pos) + + # Note that we expect someone up-stack to catch struct.error and convert + # it to _DecodeError -- this way we don't have to set up exception- + # handling blocks every time we parse one value. + result = local_unpack('<d', double_bytes)[0] + return (result, new_pos) + return _SimpleDecoder(wire_format.WIRETYPE_FIXED64, InnerDecode) + + # -------------------------------------------------------------------- @@ -294,8 +367,8 @@ Fixed32Decoder = _StructPackDecoder(wire_format.WIRETYPE_FIXED32, '<I') Fixed64Decoder = _StructPackDecoder(wire_format.WIRETYPE_FIXED64, '<Q') SFixed32Decoder = _StructPackDecoder(wire_format.WIRETYPE_FIXED32, '<i') SFixed64Decoder = _StructPackDecoder(wire_format.WIRETYPE_FIXED64, '<q') -FloatDecoder = _StructPackDecoder(wire_format.WIRETYPE_FIXED32, '<f') -DoubleDecoder = _StructPackDecoder(wire_format.WIRETYPE_FIXED64, '<d') +FloatDecoder = _FloatDecoder() +DoubleDecoder = _DoubleDecoder() BoolDecoder = _ModifiedDecoder( wire_format.WIRETYPE_VARINT, _DecodeVarint, bool) diff --git a/third_party/protobuf/python/google/protobuf/internal/encoder.py b/third_party/protobuf/python/google/protobuf/internal/encoder.py index aa05d5b..777975e 100755 --- a/third_party/protobuf/python/google/protobuf/internal/encoder.py +++ b/third_party/protobuf/python/google/protobuf/internal/encoder.py @@ -70,6 +70,12 @@ import struct from google.protobuf.internal import wire_format +# This will overflow and thus become IEEE-754 "infinity". We would use +# "float('inf')" but it doesn't work on Windows pre-Python-2.6. +_POS_INF = 1e10000 +_NEG_INF = -_POS_INF + + def _VarintSize(value): """Compute the size of a varint value.""" if value <= 0x7f: return 1 @@ -502,6 +508,83 @@ def _StructPackEncoder(wire_type, format): return SpecificEncoder +def _FloatingPointEncoder(wire_type, format): + """Return a constructor for an encoder for float fields. + + This is like StructPackEncoder, but catches errors that may be due to + passing non-finite floating-point values to struct.pack, and makes a + second attempt to encode those values. + + Args: + wire_type: The field's wire type, for encoding tags. + format: The format string to pass to struct.pack(). + """ + + value_size = struct.calcsize(format) + if value_size == 4: + def EncodeNonFiniteOrRaise(write, value): + # Remember that the serialized form uses little-endian byte order. + if value == _POS_INF: + write('\x00\x00\x80\x7F') + elif value == _NEG_INF: + write('\x00\x00\x80\xFF') + elif value != value: # NaN + write('\x00\x00\xC0\x7F') + else: + raise + elif value_size == 8: + def EncodeNonFiniteOrRaise(write, value): + if value == _POS_INF: + write('\x00\x00\x00\x00\x00\x00\xF0\x7F') + elif value == _NEG_INF: + write('\x00\x00\x00\x00\x00\x00\xF0\xFF') + elif value != value: # NaN + write('\x00\x00\x00\x00\x00\x00\xF8\x7F') + else: + raise + else: + raise ValueError('Can\'t encode floating-point values that are ' + '%d bytes long (only 4 or 8)' % value_size) + + def SpecificEncoder(field_number, is_repeated, is_packed): + local_struct_pack = struct.pack + if is_packed: + tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) + local_EncodeVarint = _EncodeVarint + def EncodePackedField(write, value): + write(tag_bytes) + local_EncodeVarint(write, len(value) * value_size) + for element in value: + # This try/except block is going to be faster than any code that + # we could write to check whether element is finite. + try: + write(local_struct_pack(format, element)) + except SystemError: + EncodeNonFiniteOrRaise(write, element) + return EncodePackedField + elif is_repeated: + tag_bytes = TagBytes(field_number, wire_type) + def EncodeRepeatedField(write, value): + for element in value: + write(tag_bytes) + try: + write(local_struct_pack(format, element)) + except SystemError: + EncodeNonFiniteOrRaise(write, element) + return EncodeRepeatedField + else: + tag_bytes = TagBytes(field_number, wire_type) + def EncodeField(write, value): + write(tag_bytes) + try: + write(local_struct_pack(format, value)) + except SystemError: + EncodeNonFiniteOrRaise(write, value) + return EncodeField + + return SpecificEncoder + + # ==================================================================== # Here we declare an encoder constructor for each field type. These work # very similarly to sizer constructors, described earlier. @@ -525,8 +608,8 @@ Fixed32Encoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED32, '<I') Fixed64Encoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED64, '<Q') SFixed32Encoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED32, '<i') SFixed64Encoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED64, '<q') -FloatEncoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED32, '<f') -DoubleEncoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED64, '<d') +FloatEncoder = _FloatingPointEncoder(wire_format.WIRETYPE_FIXED32, '<f') +DoubleEncoder = _FloatingPointEncoder(wire_format.WIRETYPE_FIXED64, '<d') def BoolEncoder(field_number, is_repeated, is_packed): diff --git a/third_party/protobuf/python/google/protobuf/internal/generator_test.py b/third_party/protobuf/python/google/protobuf/internal/generator_test.py index 78360b5..b3f7d9b1 100755 --- a/third_party/protobuf/python/google/protobuf/internal/generator_test.py +++ b/third_party/protobuf/python/google/protobuf/internal/generator_test.py @@ -42,11 +42,12 @@ further ensures that we can use Python protocol message objects as we expect. __author__ = 'robinson@google.com (Will Robinson)' import unittest +from google.protobuf import unittest_custom_options_pb2 from google.protobuf import unittest_import_pb2 from google.protobuf import unittest_mset_pb2 from google.protobuf import unittest_pb2 from google.protobuf import unittest_no_generic_services_pb2 - +from google.protobuf import service MAX_EXTENSION = 536870912 @@ -99,6 +100,7 @@ class GeneratorTest(unittest.TestCase): self.assertTrue(isinf(message.neg_inf_float)) self.assertTrue(message.neg_inf_float < 0) self.assertTrue(isnan(message.nan_float)) + self.assertEqual("? ? ?? ?? ??? ??/ ??-", message.cpp_trigraph) def testHasDefaultValues(self): desc = unittest_pb2.TestAllTypes.DESCRIPTOR @@ -140,6 +142,13 @@ class GeneratorTest(unittest.TestCase): proto = unittest_mset_pb2.TestMessageSet() self.assertTrue(proto.DESCRIPTOR.GetOptions().message_set_wire_format) + def testMessageWithCustomOptions(self): + proto = unittest_custom_options_pb2.TestMessageWithCustomOptions() + enum_options = proto.DESCRIPTOR.enum_types_by_name['AnEnum'].GetOptions() + self.assertTrue(enum_options is not None) + # TODO(gps): We really should test for the presense of the enum_opt1 + # extension and for its value to be set to -789. + def testNestedTypes(self): self.assertEquals( set(unittest_pb2.TestAllTypes.DESCRIPTOR.nested_types), @@ -208,12 +217,27 @@ class GeneratorTest(unittest.TestCase): self.assertFalse(unittest_pb2.DESCRIPTOR.serialized_pb is None) def testNoGenericServices(self): - # unittest_no_generic_services.proto should contain defs for everything - # except services. self.assertTrue(hasattr(unittest_no_generic_services_pb2, "TestMessage")) self.assertTrue(hasattr(unittest_no_generic_services_pb2, "FOO")) self.assertTrue(hasattr(unittest_no_generic_services_pb2, "test_extension")) - self.assertFalse(hasattr(unittest_no_generic_services_pb2, "TestService")) + + # Make sure unittest_no_generic_services_pb2 has no services subclassing + # Proto2 Service class. + if hasattr(unittest_no_generic_services_pb2, "TestService"): + self.assertFalse(issubclass(unittest_no_generic_services_pb2.TestService, + service.Service)) + + def testMessageTypesByName(self): + file_type = unittest_pb2.DESCRIPTOR + self.assertEqual( + unittest_pb2._TESTALLTYPES, + file_type.message_types_by_name[unittest_pb2._TESTALLTYPES.name]) + + # Nested messages shouldn't be included in the message_types_by_name + # dictionary (like in the C++ API). + self.assertFalse( + unittest_pb2._TESTALLTYPES_NESTEDMESSAGE.name in + file_type.message_types_by_name) if __name__ == '__main__': diff --git a/third_party/protobuf/python/google/protobuf/internal/message_test.py b/third_party/protobuf/python/google/protobuf/internal/message_test.py index 73a9a3a..6517437 100755 --- a/third_party/protobuf/python/google/protobuf/internal/message_test.py +++ b/third_party/protobuf/python/google/protobuf/internal/message_test.py @@ -43,11 +43,25 @@ abstract interface. __author__ = 'gps@google.com (Gregory P. Smith)' +import copy +import math import unittest from google.protobuf import unittest_import_pb2 from google.protobuf import unittest_pb2 from google.protobuf.internal import test_util +# Python pre-2.6 does not have isinf() or isnan() functions, so we have +# to provide our own. +def isnan(val): + # NaN is never equal to itself. + return val != val +def isinf(val): + # Infinity times zero equals NaN. + return not isnan(val) and isnan(val * 0) +def IsPosInf(val): + return isinf(val) and (val > 0) +def IsNegInf(val): + return isinf(val) and (val < 0) class MessageTest(unittest.TestCase): @@ -57,6 +71,8 @@ class MessageTest(unittest.TestCase): golden_message.ParseFromString(golden_data) test_util.ExpectAllFieldsSet(self, golden_message) self.assertTrue(golden_message.SerializeToString() == golden_data) + golden_copy = copy.deepcopy(golden_message) + self.assertTrue(golden_copy.SerializeToString() == golden_data) def testGoldenExtensions(self): golden_data = test_util.GoldenFile('golden_message').read() @@ -66,6 +82,8 @@ class MessageTest(unittest.TestCase): test_util.SetAllExtensions(all_set) self.assertEquals(all_set, golden_message) self.assertTrue(golden_message.SerializeToString() == golden_data) + golden_copy = copy.deepcopy(golden_message) + self.assertTrue(golden_copy.SerializeToString() == golden_data) def testGoldenPackedMessage(self): golden_data = test_util.GoldenFile('golden_packed_fields_message').read() @@ -75,6 +93,8 @@ class MessageTest(unittest.TestCase): test_util.SetAllPackedFields(all_set) self.assertEquals(all_set, golden_message) self.assertTrue(all_set.SerializeToString() == golden_data) + golden_copy = copy.deepcopy(golden_message) + self.assertTrue(golden_copy.SerializeToString() == golden_data) def testGoldenPackedExtensions(self): golden_data = test_util.GoldenFile('golden_packed_fields_message').read() @@ -84,6 +104,240 @@ class MessageTest(unittest.TestCase): test_util.SetAllPackedExtensions(all_set) self.assertEquals(all_set, golden_message) self.assertTrue(all_set.SerializeToString() == golden_data) + golden_copy = copy.deepcopy(golden_message) + self.assertTrue(golden_copy.SerializeToString() == golden_data) + + def testPositiveInfinity(self): + golden_data = ('\x5D\x00\x00\x80\x7F' + '\x61\x00\x00\x00\x00\x00\x00\xF0\x7F' + '\xCD\x02\x00\x00\x80\x7F' + '\xD1\x02\x00\x00\x00\x00\x00\x00\xF0\x7F') + golden_message = unittest_pb2.TestAllTypes() + golden_message.ParseFromString(golden_data) + self.assertTrue(IsPosInf(golden_message.optional_float)) + self.assertTrue(IsPosInf(golden_message.optional_double)) + self.assertTrue(IsPosInf(golden_message.repeated_float[0])) + self.assertTrue(IsPosInf(golden_message.repeated_double[0])) + self.assertTrue(golden_message.SerializeToString() == golden_data) + + def testNegativeInfinity(self): + golden_data = ('\x5D\x00\x00\x80\xFF' + '\x61\x00\x00\x00\x00\x00\x00\xF0\xFF' + '\xCD\x02\x00\x00\x80\xFF' + '\xD1\x02\x00\x00\x00\x00\x00\x00\xF0\xFF') + golden_message = unittest_pb2.TestAllTypes() + golden_message.ParseFromString(golden_data) + self.assertTrue(IsNegInf(golden_message.optional_float)) + self.assertTrue(IsNegInf(golden_message.optional_double)) + self.assertTrue(IsNegInf(golden_message.repeated_float[0])) + self.assertTrue(IsNegInf(golden_message.repeated_double[0])) + self.assertTrue(golden_message.SerializeToString() == golden_data) + + def testNotANumber(self): + golden_data = ('\x5D\x00\x00\xC0\x7F' + '\x61\x00\x00\x00\x00\x00\x00\xF8\x7F' + '\xCD\x02\x00\x00\xC0\x7F' + '\xD1\x02\x00\x00\x00\x00\x00\x00\xF8\x7F') + golden_message = unittest_pb2.TestAllTypes() + golden_message.ParseFromString(golden_data) + self.assertTrue(isnan(golden_message.optional_float)) + self.assertTrue(isnan(golden_message.optional_double)) + self.assertTrue(isnan(golden_message.repeated_float[0])) + self.assertTrue(isnan(golden_message.repeated_double[0])) + self.assertTrue(golden_message.SerializeToString() == golden_data) + + def testPositiveInfinityPacked(self): + golden_data = ('\xA2\x06\x04\x00\x00\x80\x7F' + '\xAA\x06\x08\x00\x00\x00\x00\x00\x00\xF0\x7F') + golden_message = unittest_pb2.TestPackedTypes() + golden_message.ParseFromString(golden_data) + self.assertTrue(IsPosInf(golden_message.packed_float[0])) + self.assertTrue(IsPosInf(golden_message.packed_double[0])) + self.assertTrue(golden_message.SerializeToString() == golden_data) + + def testNegativeInfinityPacked(self): + golden_data = ('\xA2\x06\x04\x00\x00\x80\xFF' + '\xAA\x06\x08\x00\x00\x00\x00\x00\x00\xF0\xFF') + golden_message = unittest_pb2.TestPackedTypes() + golden_message.ParseFromString(golden_data) + self.assertTrue(IsNegInf(golden_message.packed_float[0])) + self.assertTrue(IsNegInf(golden_message.packed_double[0])) + self.assertTrue(golden_message.SerializeToString() == golden_data) + + def testNotANumberPacked(self): + golden_data = ('\xA2\x06\x04\x00\x00\xC0\x7F' + '\xAA\x06\x08\x00\x00\x00\x00\x00\x00\xF8\x7F') + golden_message = unittest_pb2.TestPackedTypes() + golden_message.ParseFromString(golden_data) + self.assertTrue(isnan(golden_message.packed_float[0])) + self.assertTrue(isnan(golden_message.packed_double[0])) + self.assertTrue(golden_message.SerializeToString() == golden_data) + + def testExtremeFloatValues(self): + message = unittest_pb2.TestAllTypes() + + # Most positive exponent, no significand bits set. + kMostPosExponentNoSigBits = math.pow(2, 127) + message.optional_float = kMostPosExponentNoSigBits + message.ParseFromString(message.SerializeToString()) + self.assertTrue(message.optional_float == kMostPosExponentNoSigBits) + + # Most positive exponent, one significand bit set. + kMostPosExponentOneSigBit = 1.5 * math.pow(2, 127) + message.optional_float = kMostPosExponentOneSigBit + message.ParseFromString(message.SerializeToString()) + self.assertTrue(message.optional_float == kMostPosExponentOneSigBit) + + # Repeat last two cases with values of same magnitude, but negative. + message.optional_float = -kMostPosExponentNoSigBits + message.ParseFromString(message.SerializeToString()) + self.assertTrue(message.optional_float == -kMostPosExponentNoSigBits) + + message.optional_float = -kMostPosExponentOneSigBit + message.ParseFromString(message.SerializeToString()) + self.assertTrue(message.optional_float == -kMostPosExponentOneSigBit) + + # Most negative exponent, no significand bits set. + kMostNegExponentNoSigBits = math.pow(2, -127) + message.optional_float = kMostNegExponentNoSigBits + message.ParseFromString(message.SerializeToString()) + self.assertTrue(message.optional_float == kMostNegExponentNoSigBits) + + # Most negative exponent, one significand bit set. + kMostNegExponentOneSigBit = 1.5 * math.pow(2, -127) + message.optional_float = kMostNegExponentOneSigBit + message.ParseFromString(message.SerializeToString()) + self.assertTrue(message.optional_float == kMostNegExponentOneSigBit) + + # Repeat last two cases with values of the same magnitude, but negative. + message.optional_float = -kMostNegExponentNoSigBits + message.ParseFromString(message.SerializeToString()) + self.assertTrue(message.optional_float == -kMostNegExponentNoSigBits) + + message.optional_float = -kMostNegExponentOneSigBit + message.ParseFromString(message.SerializeToString()) + self.assertTrue(message.optional_float == -kMostNegExponentOneSigBit) + + def testExtremeFloatValues(self): + message = unittest_pb2.TestAllTypes() + + # Most positive exponent, no significand bits set. + kMostPosExponentNoSigBits = math.pow(2, 1023) + message.optional_double = kMostPosExponentNoSigBits + message.ParseFromString(message.SerializeToString()) + self.assertTrue(message.optional_double == kMostPosExponentNoSigBits) + + # Most positive exponent, one significand bit set. + kMostPosExponentOneSigBit = 1.5 * math.pow(2, 1023) + message.optional_double = kMostPosExponentOneSigBit + message.ParseFromString(message.SerializeToString()) + self.assertTrue(message.optional_double == kMostPosExponentOneSigBit) + + # Repeat last two cases with values of same magnitude, but negative. + message.optional_double = -kMostPosExponentNoSigBits + message.ParseFromString(message.SerializeToString()) + self.assertTrue(message.optional_double == -kMostPosExponentNoSigBits) + + message.optional_double = -kMostPosExponentOneSigBit + message.ParseFromString(message.SerializeToString()) + self.assertTrue(message.optional_double == -kMostPosExponentOneSigBit) + + # Most negative exponent, no significand bits set. + kMostNegExponentNoSigBits = math.pow(2, -1023) + message.optional_double = kMostNegExponentNoSigBits + message.ParseFromString(message.SerializeToString()) + self.assertTrue(message.optional_double == kMostNegExponentNoSigBits) + + # Most negative exponent, one significand bit set. + kMostNegExponentOneSigBit = 1.5 * math.pow(2, -1023) + message.optional_double = kMostNegExponentOneSigBit + message.ParseFromString(message.SerializeToString()) + self.assertTrue(message.optional_double == kMostNegExponentOneSigBit) + + # Repeat last two cases with values of the same magnitude, but negative. + message.optional_double = -kMostNegExponentNoSigBits + message.ParseFromString(message.SerializeToString()) + self.assertTrue(message.optional_double == -kMostNegExponentNoSigBits) + + message.optional_double = -kMostNegExponentOneSigBit + message.ParseFromString(message.SerializeToString()) + self.assertTrue(message.optional_double == -kMostNegExponentOneSigBit) + + def testSortingRepeatedScalarFieldsDefaultComparator(self): + """Check some different types with the default comparator.""" + message = unittest_pb2.TestAllTypes() + + # TODO(mattp): would testing more scalar types strengthen test? + message.repeated_int32.append(1) + message.repeated_int32.append(3) + message.repeated_int32.append(2) + message.repeated_int32.sort() + self.assertEqual(message.repeated_int32[0], 1) + self.assertEqual(message.repeated_int32[1], 2) + self.assertEqual(message.repeated_int32[2], 3) + + message.repeated_float.append(1.1) + message.repeated_float.append(1.3) + message.repeated_float.append(1.2) + message.repeated_float.sort() + self.assertAlmostEqual(message.repeated_float[0], 1.1) + self.assertAlmostEqual(message.repeated_float[1], 1.2) + self.assertAlmostEqual(message.repeated_float[2], 1.3) + + message.repeated_string.append('a') + message.repeated_string.append('c') + message.repeated_string.append('b') + message.repeated_string.sort() + self.assertEqual(message.repeated_string[0], 'a') + self.assertEqual(message.repeated_string[1], 'b') + self.assertEqual(message.repeated_string[2], 'c') + + message.repeated_bytes.append('a') + message.repeated_bytes.append('c') + message.repeated_bytes.append('b') + message.repeated_bytes.sort() + self.assertEqual(message.repeated_bytes[0], 'a') + self.assertEqual(message.repeated_bytes[1], 'b') + self.assertEqual(message.repeated_bytes[2], 'c') + + def testSortingRepeatedScalarFieldsCustomComparator(self): + """Check some different types with custom comparator.""" + message = unittest_pb2.TestAllTypes() + + message.repeated_int32.append(-3) + message.repeated_int32.append(-2) + message.repeated_int32.append(-1) + message.repeated_int32.sort(lambda x,y: cmp(abs(x), abs(y))) + self.assertEqual(message.repeated_int32[0], -1) + self.assertEqual(message.repeated_int32[1], -2) + self.assertEqual(message.repeated_int32[2], -3) + + message.repeated_string.append('aaa') + message.repeated_string.append('bb') + message.repeated_string.append('c') + message.repeated_string.sort(lambda x,y: cmp(len(x), len(y))) + self.assertEqual(message.repeated_string[0], 'c') + self.assertEqual(message.repeated_string[1], 'bb') + self.assertEqual(message.repeated_string[2], 'aaa') + + def testSortingRepeatedCompositeFieldsCustomComparator(self): + """Check passing a custom comparator to sort a repeated composite field.""" + message = unittest_pb2.TestAllTypes() + + message.repeated_nested_message.add().bb = 1 + message.repeated_nested_message.add().bb = 3 + message.repeated_nested_message.add().bb = 2 + message.repeated_nested_message.add().bb = 6 + message.repeated_nested_message.add().bb = 5 + message.repeated_nested_message.add().bb = 4 + message.repeated_nested_message.sort(lambda x,y: cmp(x.bb, y.bb)) + self.assertEqual(message.repeated_nested_message[0].bb, 1) + self.assertEqual(message.repeated_nested_message[1].bb, 2) + self.assertEqual(message.repeated_nested_message[2].bb, 3) + self.assertEqual(message.repeated_nested_message[3].bb, 4) + self.assertEqual(message.repeated_nested_message[4].bb, 5) + self.assertEqual(message.repeated_nested_message[5].bb, 6) + if __name__ == '__main__': unittest.main() diff --git a/third_party/protobuf/python/google/protobuf/internal/python_message.py b/third_party/protobuf/python/google/protobuf/internal/python_message.py new file mode 100644 index 0000000..66fca91 --- /dev/null +++ b/third_party/protobuf/python/google/protobuf/internal/python_message.py @@ -0,0 +1,1098 @@ +# 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. + +# This code is meant to work on Python 2.4 and above only. +# +# TODO(robinson): Helpers for verbose, common checks like seeing if a +# descriptor's cpp_type is CPPTYPE_MESSAGE. + +"""Contains a metaclass and helper functions used to create +protocol message classes from Descriptor objects at runtime. + +Recall that a metaclass is the "type" of a class. +(A class is to a metaclass what an instance is to a class.) + +In this case, we use the GeneratedProtocolMessageType metaclass +to inject all the useful functionality into the classes +output by the protocol compiler at compile-time. + +The upshot of all this is that the real implementation +details for ALL pure-Python protocol buffers are *here in +this file*. +""" + +__author__ = 'robinson@google.com (Will Robinson)' + +try: + from cStringIO import StringIO +except ImportError: + from StringIO import StringIO +import struct +import weakref + +# We use "as" to avoid name collisions with variables. +from google.protobuf.internal import containers +from google.protobuf.internal import decoder +from google.protobuf.internal import encoder +from google.protobuf.internal import message_listener as message_listener_mod +from google.protobuf.internal import type_checkers +from google.protobuf.internal import wire_format +from google.protobuf import descriptor as descriptor_mod +from google.protobuf import message as message_mod +from google.protobuf import text_format + +_FieldDescriptor = descriptor_mod.FieldDescriptor + + +def NewMessage(descriptor, dictionary): + _AddClassAttributesForNestedExtensions(descriptor, dictionary) + _AddSlots(descriptor, dictionary) + + +def InitMessage(descriptor, cls): + cls._decoders_by_tag = {} + cls._extensions_by_name = {} + cls._extensions_by_number = {} + if (descriptor.has_options and + descriptor.GetOptions().message_set_wire_format): + cls._decoders_by_tag[decoder.MESSAGE_SET_ITEM_TAG] = ( + decoder.MessageSetItemDecoder(cls._extensions_by_number)) + + # Attach stuff to each FieldDescriptor for quick lookup later on. + for field in descriptor.fields: + _AttachFieldHelpers(cls, field) + + _AddEnumValues(descriptor, cls) + _AddInitMethod(descriptor, cls) + _AddPropertiesForFields(descriptor, cls) + _AddPropertiesForExtensions(descriptor, cls) + _AddStaticMethods(cls) + _AddMessageMethods(descriptor, cls) + _AddPrivateHelperMethods(cls) + + +# Stateless helpers for GeneratedProtocolMessageType below. +# Outside clients should not access these directly. +# +# I opted not to make any of these methods on the metaclass, to make it more +# clear that I'm not really using any state there and to keep clients from +# thinking that they have direct access to these construction helpers. + + +def _PropertyName(proto_field_name): + """Returns the name of the public property attribute which + clients can use to get and (in some cases) set the value + of a protocol message field. + + Args: + proto_field_name: The protocol message field name, exactly + as it appears (or would appear) in a .proto file. + """ + # TODO(robinson): Escape Python keywords (e.g., yield), and test this support. + # nnorwitz makes my day by writing: + # """ + # FYI. See the keyword module in the stdlib. This could be as simple as: + # + # if keyword.iskeyword(proto_field_name): + # return proto_field_name + "_" + # return proto_field_name + # """ + # Kenton says: The above is a BAD IDEA. People rely on being able to use + # getattr() and setattr() to reflectively manipulate field values. If we + # rename the properties, then every such user has to also make sure to apply + # the same transformation. Note that currently if you name a field "yield", + # you can still access it just fine using getattr/setattr -- it's not even + # that cumbersome to do so. + # TODO(kenton): Remove this method entirely if/when everyone agrees with my + # position. + return proto_field_name + + +def _VerifyExtensionHandle(message, extension_handle): + """Verify that the given extension handle is valid.""" + + if not isinstance(extension_handle, _FieldDescriptor): + raise KeyError('HasExtension() expects an extension handle, got: %s' % + extension_handle) + + if not extension_handle.is_extension: + raise KeyError('"%s" is not an extension.' % extension_handle.full_name) + + if extension_handle.containing_type is not message.DESCRIPTOR: + raise KeyError('Extension "%s" extends message type "%s", but this ' + 'message is of type "%s".' % + (extension_handle.full_name, + extension_handle.containing_type.full_name, + message.DESCRIPTOR.full_name)) + + +def _AddSlots(message_descriptor, dictionary): + """Adds a __slots__ entry to dictionary, containing the names of all valid + attributes for this message type. + + Args: + message_descriptor: A Descriptor instance describing this message type. + dictionary: Class dictionary to which we'll add a '__slots__' entry. + """ + dictionary['__slots__'] = ['_cached_byte_size', + '_cached_byte_size_dirty', + '_fields', + '_is_present_in_parent', + '_listener', + '_listener_for_children', + '__weakref__'] + + +def _IsMessageSetExtension(field): + return (field.is_extension and + field.containing_type.has_options and + field.containing_type.GetOptions().message_set_wire_format and + field.type == _FieldDescriptor.TYPE_MESSAGE and + field.message_type == field.extension_scope and + field.label == _FieldDescriptor.LABEL_OPTIONAL) + + +def _AttachFieldHelpers(cls, field_descriptor): + is_repeated = (field_descriptor.label == _FieldDescriptor.LABEL_REPEATED) + is_packed = (field_descriptor.has_options and + field_descriptor.GetOptions().packed) + + if _IsMessageSetExtension(field_descriptor): + field_encoder = encoder.MessageSetItemEncoder(field_descriptor.number) + sizer = encoder.MessageSetItemSizer(field_descriptor.number) + else: + field_encoder = type_checkers.TYPE_TO_ENCODER[field_descriptor.type]( + field_descriptor.number, is_repeated, is_packed) + sizer = type_checkers.TYPE_TO_SIZER[field_descriptor.type]( + field_descriptor.number, is_repeated, is_packed) + + field_descriptor._encoder = field_encoder + field_descriptor._sizer = sizer + field_descriptor._default_constructor = _DefaultValueConstructorForField( + field_descriptor) + + def AddDecoder(wiretype, is_packed): + tag_bytes = encoder.TagBytes(field_descriptor.number, wiretype) + cls._decoders_by_tag[tag_bytes] = ( + type_checkers.TYPE_TO_DECODER[field_descriptor.type]( + field_descriptor.number, is_repeated, is_packed, + field_descriptor, field_descriptor._default_constructor)) + + AddDecoder(type_checkers.FIELD_TYPE_TO_WIRE_TYPE[field_descriptor.type], + False) + + if is_repeated and wire_format.IsTypePackable(field_descriptor.type): + # To support wire compatibility of adding packed = true, add a decoder for + # packed values regardless of the field's options. + AddDecoder(wire_format.WIRETYPE_LENGTH_DELIMITED, True) + + +def _AddClassAttributesForNestedExtensions(descriptor, dictionary): + extension_dict = descriptor.extensions_by_name + for extension_name, extension_field in extension_dict.iteritems(): + assert extension_name not in dictionary + dictionary[extension_name] = extension_field + + +def _AddEnumValues(descriptor, cls): + """Sets class-level attributes for all enum fields defined in this message. + + Args: + descriptor: Descriptor object for this message type. + cls: Class we're constructing for this message type. + """ + for enum_type in descriptor.enum_types: + for enum_value in enum_type.values: + setattr(cls, enum_value.name, enum_value.number) + + +def _DefaultValueConstructorForField(field): + """Returns a function which returns a default value for a field. + + Args: + field: FieldDescriptor object for this field. + + The returned function has one argument: + message: Message instance containing this field, or a weakref proxy + of same. + + That function in turn returns a default value for this field. The default + value may refer back to |message| via a weak reference. + """ + + if field.label == _FieldDescriptor.LABEL_REPEATED: + if field.default_value != []: + raise ValueError('Repeated field default value not empty list: %s' % ( + field.default_value)) + if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: + # We can't look at _concrete_class yet since it might not have + # been set. (Depends on order in which we initialize the classes). + message_type = field.message_type + def MakeRepeatedMessageDefault(message): + return containers.RepeatedCompositeFieldContainer( + message._listener_for_children, field.message_type) + return MakeRepeatedMessageDefault + else: + type_checker = type_checkers.GetTypeChecker(field.cpp_type, field.type) + def MakeRepeatedScalarDefault(message): + return containers.RepeatedScalarFieldContainer( + message._listener_for_children, type_checker) + return MakeRepeatedScalarDefault + + if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: + # _concrete_class may not yet be initialized. + message_type = field.message_type + def MakeSubMessageDefault(message): + result = message_type._concrete_class() + result._SetListener(message._listener_for_children) + return result + return MakeSubMessageDefault + + def MakeScalarDefault(message): + return field.default_value + return MakeScalarDefault + + +def _AddInitMethod(message_descriptor, cls): + """Adds an __init__ method to cls.""" + fields = message_descriptor.fields + def init(self, **kwargs): + self._cached_byte_size = 0 + self._cached_byte_size_dirty = len(kwargs) > 0 + self._fields = {} + self._is_present_in_parent = False + self._listener = message_listener_mod.NullMessageListener() + self._listener_for_children = _Listener(self) + for field_name, field_value in kwargs.iteritems(): + field = _GetFieldByName(message_descriptor, field_name) + if field is None: + raise TypeError("%s() got an unexpected keyword argument '%s'" % + (message_descriptor.name, field_name)) + if field.label == _FieldDescriptor.LABEL_REPEATED: + copy = field._default_constructor(self) + if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: # Composite + for val in field_value: + copy.add().MergeFrom(val) + else: # Scalar + copy.extend(field_value) + self._fields[field] = copy + elif field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: + copy = field._default_constructor(self) + copy.MergeFrom(field_value) + self._fields[field] = copy + else: + setattr(self, field_name, field_value) + + init.__module__ = None + init.__doc__ = None + cls.__init__ = init + + +def _GetFieldByName(message_descriptor, field_name): + """Returns a field descriptor by field name. + + Args: + message_descriptor: A Descriptor describing all fields in message. + field_name: The name of the field to retrieve. + Returns: + The field descriptor associated with the field name. + """ + try: + return message_descriptor.fields_by_name[field_name] + except KeyError: + raise ValueError('Protocol message has no "%s" field.' % field_name) + + +def _AddPropertiesForFields(descriptor, cls): + """Adds properties for all fields in this protocol message type.""" + for field in descriptor.fields: + _AddPropertiesForField(field, cls) + + if descriptor.is_extendable: + # _ExtensionDict is just an adaptor with no state so we allocate a new one + # every time it is accessed. + cls.Extensions = property(lambda self: _ExtensionDict(self)) + + +def _AddPropertiesForField(field, cls): + """Adds a public property for a protocol message field. + Clients can use this property to get and (in the case + of non-repeated scalar fields) directly set the value + of a protocol message field. + + Args: + field: A FieldDescriptor for this field. + cls: The class we're constructing. + """ + # Catch it if we add other types that we should + # handle specially here. + assert _FieldDescriptor.MAX_CPPTYPE == 10 + + constant_name = field.name.upper() + "_FIELD_NUMBER" + setattr(cls, constant_name, field.number) + + if field.label == _FieldDescriptor.LABEL_REPEATED: + _AddPropertiesForRepeatedField(field, cls) + elif field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: + _AddPropertiesForNonRepeatedCompositeField(field, cls) + else: + _AddPropertiesForNonRepeatedScalarField(field, cls) + + +def _AddPropertiesForRepeatedField(field, cls): + """Adds a public property for a "repeated" protocol message field. Clients + can use this property to get the value of the field, which will be either a + _RepeatedScalarFieldContainer or _RepeatedCompositeFieldContainer (see + below). + + Note that when clients add values to these containers, we perform + type-checking in the case of repeated scalar fields, and we also set any + necessary "has" bits as a side-effect. + + Args: + field: A FieldDescriptor for this field. + cls: The class we're constructing. + """ + proto_field_name = field.name + property_name = _PropertyName(proto_field_name) + + def getter(self): + field_value = self._fields.get(field) + if field_value is None: + # Construct a new object to represent this field. + field_value = field._default_constructor(self) + + # Atomically check if another thread has preempted us and, if not, swap + # in the new object we just created. If someone has preempted us, we + # take that object and discard ours. + # WARNING: We are relying on setdefault() being atomic. This is true + # in CPython but we haven't investigated others. This warning appears + # in several other locations in this file. + field_value = self._fields.setdefault(field, field_value) + return field_value + getter.__module__ = None + getter.__doc__ = 'Getter for %s.' % proto_field_name + + # We define a setter just so we can throw an exception with a more + # helpful error message. + def setter(self, new_value): + raise AttributeError('Assignment not allowed to repeated field ' + '"%s" in protocol message object.' % proto_field_name) + + doc = 'Magic attribute generated for "%s" proto field.' % proto_field_name + setattr(cls, property_name, property(getter, setter, doc=doc)) + + +def _AddPropertiesForNonRepeatedScalarField(field, cls): + """Adds a public property for a nonrepeated, scalar protocol message field. + Clients can use this property to get and directly set the value of the field. + Note that when the client sets the value of a field by using this property, + all necessary "has" bits are set as a side-effect, and we also perform + type-checking. + + Args: + field: A FieldDescriptor for this field. + cls: The class we're constructing. + """ + proto_field_name = field.name + property_name = _PropertyName(proto_field_name) + type_checker = type_checkers.GetTypeChecker(field.cpp_type, field.type) + default_value = field.default_value + valid_values = set() + + def getter(self): + return self._fields.get(field, default_value) + getter.__module__ = None + getter.__doc__ = 'Getter for %s.' % proto_field_name + def setter(self, new_value): + type_checker.CheckValue(new_value) + self._fields[field] = new_value + # Check _cached_byte_size_dirty inline to improve performance, since scalar + # setters are called frequently. + if not self._cached_byte_size_dirty: + self._Modified() + + setter.__module__ = None + setter.__doc__ = 'Setter for %s.' % proto_field_name + + # Add a property to encapsulate the getter/setter. + doc = 'Magic attribute generated for "%s" proto field.' % proto_field_name + setattr(cls, property_name, property(getter, setter, doc=doc)) + + +def _AddPropertiesForNonRepeatedCompositeField(field, cls): + """Adds a public property for a nonrepeated, composite protocol message field. + A composite field is a "group" or "message" field. + + Clients can use this property to get the value of the field, but cannot + assign to the property directly. + + Args: + field: A FieldDescriptor for this field. + cls: The class we're constructing. + """ + # TODO(robinson): Remove duplication with similar method + # for non-repeated scalars. + proto_field_name = field.name + property_name = _PropertyName(proto_field_name) + message_type = field.message_type + + def getter(self): + field_value = self._fields.get(field) + if field_value is None: + # Construct a new object to represent this field. + field_value = message_type._concrete_class() + field_value._SetListener(self._listener_for_children) + + # Atomically check if another thread has preempted us and, if not, swap + # in the new object we just created. If someone has preempted us, we + # take that object and discard ours. + # WARNING: We are relying on setdefault() being atomic. This is true + # in CPython but we haven't investigated others. This warning appears + # in several other locations in this file. + field_value = self._fields.setdefault(field, field_value) + return field_value + getter.__module__ = None + getter.__doc__ = 'Getter for %s.' % proto_field_name + + # We define a setter just so we can throw an exception with a more + # helpful error message. + def setter(self, new_value): + raise AttributeError('Assignment not allowed to composite field ' + '"%s" in protocol message object.' % proto_field_name) + + # Add a property to encapsulate the getter. + doc = 'Magic attribute generated for "%s" proto field.' % proto_field_name + setattr(cls, property_name, property(getter, setter, doc=doc)) + + +def _AddPropertiesForExtensions(descriptor, cls): + """Adds properties for all fields in this protocol message type.""" + extension_dict = descriptor.extensions_by_name + for extension_name, extension_field in extension_dict.iteritems(): + constant_name = extension_name.upper() + "_FIELD_NUMBER" + setattr(cls, constant_name, extension_field.number) + + +def _AddStaticMethods(cls): + # TODO(robinson): This probably needs to be thread-safe(?) + def RegisterExtension(extension_handle): + extension_handle.containing_type = cls.DESCRIPTOR + _AttachFieldHelpers(cls, extension_handle) + + # Try to insert our extension, failing if an extension with the same number + # already exists. + actual_handle = cls._extensions_by_number.setdefault( + extension_handle.number, extension_handle) + if actual_handle is not extension_handle: + raise AssertionError( + 'Extensions "%s" and "%s" both try to extend message type "%s" with ' + 'field number %d.' % + (extension_handle.full_name, actual_handle.full_name, + cls.DESCRIPTOR.full_name, extension_handle.number)) + + cls._extensions_by_name[extension_handle.full_name] = extension_handle + + handle = extension_handle # avoid line wrapping + if _IsMessageSetExtension(handle): + # MessageSet extension. Also register under type name. + cls._extensions_by_name[ + extension_handle.message_type.full_name] = extension_handle + + cls.RegisterExtension = staticmethod(RegisterExtension) + + def FromString(s): + message = cls() + message.MergeFromString(s) + return message + cls.FromString = staticmethod(FromString) + + +def _IsPresent(item): + """Given a (FieldDescriptor, value) tuple from _fields, return true if the + value should be included in the list returned by ListFields().""" + + if item[0].label == _FieldDescriptor.LABEL_REPEATED: + return bool(item[1]) + elif item[0].cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: + return item[1]._is_present_in_parent + else: + return True + + +def _AddListFieldsMethod(message_descriptor, cls): + """Helper for _AddMessageMethods().""" + + def ListFields(self): + all_fields = [item for item in self._fields.iteritems() if _IsPresent(item)] + all_fields.sort(key = lambda item: item[0].number) + return all_fields + + cls.ListFields = ListFields + + +def _AddHasFieldMethod(message_descriptor, cls): + """Helper for _AddMessageMethods().""" + + singular_fields = {} + for field in message_descriptor.fields: + if field.label != _FieldDescriptor.LABEL_REPEATED: + singular_fields[field.name] = field + + def HasField(self, field_name): + try: + field = singular_fields[field_name] + except KeyError: + raise ValueError( + 'Protocol message has no singular "%s" field.' % field_name) + + if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: + value = self._fields.get(field) + return value is not None and value._is_present_in_parent + else: + return field in self._fields + cls.HasField = HasField + + +def _AddClearFieldMethod(message_descriptor, cls): + """Helper for _AddMessageMethods().""" + def ClearField(self, field_name): + try: + field = message_descriptor.fields_by_name[field_name] + except KeyError: + raise ValueError('Protocol message has no "%s" field.' % field_name) + + if field in self._fields: + # Note: If the field is a sub-message, its listener will still point + # at us. That's fine, because the worst than can happen is that it + # will call _Modified() and invalidate our byte size. Big deal. + del self._fields[field] + + # Always call _Modified() -- even if nothing was changed, this is + # a mutating method, and thus calling it should cause the field to become + # present in the parent message. + self._Modified() + + cls.ClearField = ClearField + + +def _AddClearExtensionMethod(cls): + """Helper for _AddMessageMethods().""" + def ClearExtension(self, extension_handle): + _VerifyExtensionHandle(self, extension_handle) + + # Similar to ClearField(), above. + if extension_handle in self._fields: + del self._fields[extension_handle] + self._Modified() + cls.ClearExtension = ClearExtension + + +def _AddClearMethod(message_descriptor, cls): + """Helper for _AddMessageMethods().""" + def Clear(self): + # Clear fields. + self._fields = {} + self._Modified() + cls.Clear = Clear + + +def _AddHasExtensionMethod(cls): + """Helper for _AddMessageMethods().""" + def HasExtension(self, extension_handle): + _VerifyExtensionHandle(self, extension_handle) + if extension_handle.label == _FieldDescriptor.LABEL_REPEATED: + raise KeyError('"%s" is repeated.' % extension_handle.full_name) + + if extension_handle.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: + value = self._fields.get(extension_handle) + return value is not None and value._is_present_in_parent + else: + return extension_handle in self._fields + cls.HasExtension = HasExtension + + +def _AddEqualsMethod(message_descriptor, cls): + """Helper for _AddMessageMethods().""" + def __eq__(self, other): + if (not isinstance(other, message_mod.Message) or + other.DESCRIPTOR != self.DESCRIPTOR): + return False + + if self is other: + return True + + return self.ListFields() == other.ListFields() + + cls.__eq__ = __eq__ + + +def _AddStrMethod(message_descriptor, cls): + """Helper for _AddMessageMethods().""" + def __str__(self): + return text_format.MessageToString(self) + cls.__str__ = __str__ + + +def _AddUnicodeMethod(unused_message_descriptor, cls): + """Helper for _AddMessageMethods().""" + + def __unicode__(self): + return text_format.MessageToString(self, as_utf8=True).decode('utf-8') + cls.__unicode__ = __unicode__ + + +def _AddSetListenerMethod(cls): + """Helper for _AddMessageMethods().""" + def SetListener(self, listener): + if listener is None: + self._listener = message_listener_mod.NullMessageListener() + else: + self._listener = listener + cls._SetListener = SetListener + + +def _BytesForNonRepeatedElement(value, field_number, field_type): + """Returns the number of bytes needed to serialize a non-repeated element. + The returned byte count includes space for tag information and any + other additional space associated with serializing value. + + Args: + value: Value we're serializing. + field_number: Field number of this value. (Since the field number + is stored as part of a varint-encoded tag, this has an impact + on the total bytes required to serialize the value). + field_type: The type of the field. One of the TYPE_* constants + within FieldDescriptor. + """ + try: + fn = type_checkers.TYPE_TO_BYTE_SIZE_FN[field_type] + return fn(field_number, value) + except KeyError: + raise message_mod.EncodeError('Unrecognized field type: %d' % field_type) + + +def _AddByteSizeMethod(message_descriptor, cls): + """Helper for _AddMessageMethods().""" + + def ByteSize(self): + if not self._cached_byte_size_dirty: + return self._cached_byte_size + + size = 0 + for field_descriptor, field_value in self.ListFields(): + size += field_descriptor._sizer(field_value) + + self._cached_byte_size = size + self._cached_byte_size_dirty = False + self._listener_for_children.dirty = False + return size + + cls.ByteSize = ByteSize + + +def _AddSerializeToStringMethod(message_descriptor, cls): + """Helper for _AddMessageMethods().""" + + def SerializeToString(self): + # Check if the message has all of its required fields set. + errors = [] + if not self.IsInitialized(): + raise message_mod.EncodeError( + 'Message is missing required fields: ' + + ','.join(self.FindInitializationErrors())) + return self.SerializePartialToString() + cls.SerializeToString = SerializeToString + + +def _AddSerializePartialToStringMethod(message_descriptor, cls): + """Helper for _AddMessageMethods().""" + + def SerializePartialToString(self): + out = StringIO() + self._InternalSerialize(out.write) + return out.getvalue() + cls.SerializePartialToString = SerializePartialToString + + def InternalSerialize(self, write_bytes): + for field_descriptor, field_value in self.ListFields(): + field_descriptor._encoder(write_bytes, field_value) + cls._InternalSerialize = InternalSerialize + + +def _AddMergeFromStringMethod(message_descriptor, cls): + """Helper for _AddMessageMethods().""" + def MergeFromString(self, serialized): + length = len(serialized) + try: + if self._InternalParse(serialized, 0, length) != length: + # The only reason _InternalParse would return early is if it + # encountered an end-group tag. + raise message_mod.DecodeError('Unexpected end-group tag.') + except IndexError: + raise message_mod.DecodeError('Truncated message.') + except struct.error, e: + raise message_mod.DecodeError(e) + return length # Return this for legacy reasons. + cls.MergeFromString = MergeFromString + + local_ReadTag = decoder.ReadTag + local_SkipField = decoder.SkipField + decoders_by_tag = cls._decoders_by_tag + + def InternalParse(self, buffer, pos, end): + self._Modified() + field_dict = self._fields + while pos != end: + (tag_bytes, new_pos) = local_ReadTag(buffer, pos) + field_decoder = decoders_by_tag.get(tag_bytes) + if field_decoder is None: + new_pos = local_SkipField(buffer, new_pos, end, tag_bytes) + if new_pos == -1: + return pos + pos = new_pos + else: + pos = field_decoder(buffer, new_pos, end, self, field_dict) + return pos + cls._InternalParse = InternalParse + + +def _AddIsInitializedMethod(message_descriptor, cls): + """Adds the IsInitialized and FindInitializationError methods to the + protocol message class.""" + + required_fields = [field for field in message_descriptor.fields + if field.label == _FieldDescriptor.LABEL_REQUIRED] + + def IsInitialized(self, errors=None): + """Checks if all required fields of a message are set. + + Args: + errors: A list which, if provided, will be populated with the field + paths of all missing required fields. + + Returns: + True iff the specified message has all required fields set. + """ + + # Performance is critical so we avoid HasField() and ListFields(). + + for field in required_fields: + if (field not in self._fields or + (field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE and + not self._fields[field]._is_present_in_parent)): + if errors is not None: + errors.extend(self.FindInitializationErrors()) + return False + + for field, value in self._fields.iteritems(): + if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: + if field.label == _FieldDescriptor.LABEL_REPEATED: + for element in value: + if not element.IsInitialized(): + if errors is not None: + errors.extend(self.FindInitializationErrors()) + return False + elif value._is_present_in_parent and not value.IsInitialized(): + if errors is not None: + errors.extend(self.FindInitializationErrors()) + return False + + return True + + cls.IsInitialized = IsInitialized + + def FindInitializationErrors(self): + """Finds required fields which are not initialized. + + Returns: + A list of strings. Each string is a path to an uninitialized field from + the top-level message, e.g. "foo.bar[5].baz". + """ + + errors = [] # simplify things + + for field in required_fields: + if not self.HasField(field.name): + errors.append(field.name) + + for field, value in self.ListFields(): + if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: + if field.is_extension: + name = "(%s)" % field.full_name + else: + name = field.name + + if field.label == _FieldDescriptor.LABEL_REPEATED: + for i in xrange(len(value)): + element = value[i] + prefix = "%s[%d]." % (name, i) + sub_errors = element.FindInitializationErrors() + errors += [ prefix + error for error in sub_errors ] + else: + prefix = name + "." + sub_errors = value.FindInitializationErrors() + errors += [ prefix + error for error in sub_errors ] + + return errors + + cls.FindInitializationErrors = FindInitializationErrors + + +def _AddMergeFromMethod(cls): + LABEL_REPEATED = _FieldDescriptor.LABEL_REPEATED + CPPTYPE_MESSAGE = _FieldDescriptor.CPPTYPE_MESSAGE + + def MergeFrom(self, msg): + if not isinstance(msg, cls): + raise TypeError( + "Parameter to MergeFrom() must be instance of same class.") + + assert msg is not self + self._Modified() + + fields = self._fields + + for field, value in msg._fields.iteritems(): + if field.label == LABEL_REPEATED: + field_value = fields.get(field) + if field_value is None: + # Construct a new object to represent this field. + field_value = field._default_constructor(self) + fields[field] = field_value + field_value.MergeFrom(value) + elif field.cpp_type == CPPTYPE_MESSAGE: + if value._is_present_in_parent: + field_value = fields.get(field) + if field_value is None: + # Construct a new object to represent this field. + field_value = field._default_constructor(self) + fields[field] = field_value + field_value.MergeFrom(value) + else: + self._fields[field] = value + cls.MergeFrom = MergeFrom + + +def _AddMessageMethods(message_descriptor, cls): + """Adds implementations of all Message methods to cls.""" + _AddListFieldsMethod(message_descriptor, cls) + _AddHasFieldMethod(message_descriptor, cls) + _AddClearFieldMethod(message_descriptor, cls) + if message_descriptor.is_extendable: + _AddClearExtensionMethod(cls) + _AddHasExtensionMethod(cls) + _AddClearMethod(message_descriptor, cls) + _AddEqualsMethod(message_descriptor, cls) + _AddStrMethod(message_descriptor, cls) + _AddUnicodeMethod(message_descriptor, cls) + _AddSetListenerMethod(cls) + _AddByteSizeMethod(message_descriptor, cls) + _AddSerializeToStringMethod(message_descriptor, cls) + _AddSerializePartialToStringMethod(message_descriptor, cls) + _AddMergeFromStringMethod(message_descriptor, cls) + _AddIsInitializedMethod(message_descriptor, cls) + _AddMergeFromMethod(cls) + + +def _AddPrivateHelperMethods(cls): + """Adds implementation of private helper methods to cls.""" + + def Modified(self): + """Sets the _cached_byte_size_dirty bit to true, + and propagates this to our listener iff this was a state change. + """ + + # Note: Some callers check _cached_byte_size_dirty before calling + # _Modified() as an extra optimization. So, if this method is ever + # changed such that it does stuff even when _cached_byte_size_dirty is + # already true, the callers need to be updated. + if not self._cached_byte_size_dirty: + self._cached_byte_size_dirty = True + self._listener_for_children.dirty = True + self._is_present_in_parent = True + self._listener.Modified() + + cls._Modified = Modified + cls.SetInParent = Modified + + +class _Listener(object): + + """MessageListener implementation that a parent message registers with its + child message. + + In order to support semantics like: + + foo.bar.baz.qux = 23 + assert foo.HasField('bar') + + ...child objects must have back references to their parents. + This helper class is at the heart of this support. + """ + + def __init__(self, parent_message): + """Args: + parent_message: The message whose _Modified() method we should call when + we receive Modified() messages. + """ + # This listener establishes a back reference from a child (contained) object + # to its parent (containing) object. We make this a weak reference to avoid + # creating cyclic garbage when the client finishes with the 'parent' object + # in the tree. + if isinstance(parent_message, weakref.ProxyType): + self._parent_message_weakref = parent_message + else: + self._parent_message_weakref = weakref.proxy(parent_message) + + # As an optimization, we also indicate directly on the listener whether + # or not the parent message is dirty. This way we can avoid traversing + # up the tree in the common case. + self.dirty = False + + def Modified(self): + if self.dirty: + return + try: + # Propagate the signal to our parents iff this is the first field set. + self._parent_message_weakref._Modified() + except ReferenceError: + # We can get here if a client has kept a reference to a child object, + # and is now setting a field on it, but the child's parent has been + # garbage-collected. This is not an error. + pass + + +# TODO(robinson): Move elsewhere? This file is getting pretty ridiculous... +# TODO(robinson): Unify error handling of "unknown extension" crap. +# TODO(robinson): Support iteritems()-style iteration over all +# extensions with the "has" bits turned on? +class _ExtensionDict(object): + + """Dict-like container for supporting an indexable "Extensions" + field on proto instances. + + Note that in all cases we expect extension handles to be + FieldDescriptors. + """ + + def __init__(self, extended_message): + """extended_message: Message instance for which we are the Extensions dict. + """ + + self._extended_message = extended_message + + def __getitem__(self, extension_handle): + """Returns the current value of the given extension handle.""" + + _VerifyExtensionHandle(self._extended_message, extension_handle) + + result = self._extended_message._fields.get(extension_handle) + if result is not None: + return result + + if extension_handle.label == _FieldDescriptor.LABEL_REPEATED: + result = extension_handle._default_constructor(self._extended_message) + elif extension_handle.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: + result = extension_handle.message_type._concrete_class() + try: + result._SetListener(self._extended_message._listener_for_children) + except ReferenceError: + pass + else: + # Singular scalar -- just return the default without inserting into the + # dict. + return extension_handle.default_value + + # Atomically check if another thread has preempted us and, if not, swap + # in the new object we just created. If someone has preempted us, we + # take that object and discard ours. + # WARNING: We are relying on setdefault() being atomic. This is true + # in CPython but we haven't investigated others. This warning appears + # in several other locations in this file. + result = self._extended_message._fields.setdefault( + extension_handle, result) + + return result + + def __eq__(self, other): + if not isinstance(other, self.__class__): + return False + + my_fields = self._extended_message.ListFields() + other_fields = other._extended_message.ListFields() + + # Get rid of non-extension fields. + my_fields = [ field for field in my_fields if field.is_extension ] + other_fields = [ field for field in other_fields if field.is_extension ] + + return my_fields == other_fields + + def __ne__(self, other): + return not self == other + + def __hash__(self): + raise TypeError('unhashable object') + + # Note that this is only meaningful for non-repeated, scalar extension + # fields. Note also that we may have to call _Modified() when we do + # successfully set a field this way, to set any necssary "has" bits in the + # ancestors of the extended message. + def __setitem__(self, extension_handle, value): + """If extension_handle specifies a non-repeated, scalar extension + field, sets the value of that field. + """ + + _VerifyExtensionHandle(self._extended_message, extension_handle) + + if (extension_handle.label == _FieldDescriptor.LABEL_REPEATED or + extension_handle.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE): + raise TypeError( + 'Cannot assign to extension "%s" because it is a repeated or ' + 'composite type.' % extension_handle.full_name) + + # It's slightly wasteful to lookup the type checker each time, + # but we expect this to be a vanishingly uncommon case anyway. + type_checker = type_checkers.GetTypeChecker( + extension_handle.cpp_type, extension_handle.type) + type_checker.CheckValue(value) + self._extended_message._fields[extension_handle] = value + self._extended_message._Modified() + + def _FindExtensionByName(self, name): + """Tries to find a known extension with the specified name. + + Args: + name: Extension full name. + + Returns: + Extension field descriptor. + """ + return self._extended_message._extensions_by_name.get(name, None) diff --git a/third_party/protobuf/python/google/protobuf/internal/reflection_test.py b/third_party/protobuf/python/google/protobuf/internal/reflection_test.py index 54eeebe..7b9d339 100755 --- a/third_party/protobuf/python/google/protobuf/internal/reflection_test.py +++ b/third_party/protobuf/python/google/protobuf/internal/reflection_test.py @@ -41,8 +41,6 @@ import operator import struct import unittest -# TODO(robinson): When we split this test in two, only some of these imports -# will be necessary in each test. from google.protobuf import unittest_import_pb2 from google.protobuf import unittest_mset_pb2 from google.protobuf import unittest_pb2 @@ -50,6 +48,7 @@ from google.protobuf import descriptor_pb2 from google.protobuf import descriptor from google.protobuf import message from google.protobuf import reflection +from google.protobuf.internal import api_implementation from google.protobuf.internal import more_extensions_pb2 from google.protobuf.internal import more_messages_pb2 from google.protobuf.internal import wire_format @@ -104,10 +103,10 @@ class _MiniDecoder(object): class ReflectionTest(unittest.TestCase): - def assertIs(self, values, others): + def assertListsEqual(self, values, others): self.assertEqual(len(values), len(others)) for i in range(len(values)): - self.assertTrue(values[i] is others[i]) + self.assertEqual(values[i], others[i]) def testScalarConstructor(self): # Constructor with only scalar types should succeed. @@ -201,15 +200,24 @@ class ReflectionTest(unittest.TestCase): list(proto.repeated_foreign_message)) def testConstructorTypeError(self): - self.assertRaises(TypeError, unittest_pb2.TestAllTypes, optional_int32="foo") - self.assertRaises(TypeError, unittest_pb2.TestAllTypes, optional_string=1234) - self.assertRaises(TypeError, unittest_pb2.TestAllTypes, optional_nested_message=1234) - self.assertRaises(TypeError, unittest_pb2.TestAllTypes, repeated_int32=1234) - self.assertRaises(TypeError, unittest_pb2.TestAllTypes, repeated_int32=["foo"]) - self.assertRaises(TypeError, unittest_pb2.TestAllTypes, repeated_string=1234) - self.assertRaises(TypeError, unittest_pb2.TestAllTypes, repeated_string=[1234]) - self.assertRaises(TypeError, unittest_pb2.TestAllTypes, repeated_nested_message=1234) - self.assertRaises(TypeError, unittest_pb2.TestAllTypes, repeated_nested_message=[1234]) + self.assertRaises( + TypeError, unittest_pb2.TestAllTypes, optional_int32="foo") + self.assertRaises( + TypeError, unittest_pb2.TestAllTypes, optional_string=1234) + self.assertRaises( + TypeError, unittest_pb2.TestAllTypes, optional_nested_message=1234) + self.assertRaises( + TypeError, unittest_pb2.TestAllTypes, repeated_int32=1234) + self.assertRaises( + TypeError, unittest_pb2.TestAllTypes, repeated_int32=["foo"]) + self.assertRaises( + TypeError, unittest_pb2.TestAllTypes, repeated_string=1234) + self.assertRaises( + TypeError, unittest_pb2.TestAllTypes, repeated_string=[1234]) + self.assertRaises( + TypeError, unittest_pb2.TestAllTypes, repeated_nested_message=1234) + self.assertRaises( + TypeError, unittest_pb2.TestAllTypes, repeated_nested_message=[1234]) def testConstructorInvalidatesCachedByteSize(self): message = unittest_pb2.TestAllTypes(optional_int32 = 12) @@ -311,11 +319,14 @@ class ReflectionTest(unittest.TestCase): self.assertEqual(0, getattr(composite_field, scalar_field_name)) # Finally, ensure that modifications to the old composite field object - # don't have any effect on the parent. + # don't have any effect on the parent. Possible only with the pure-python + # implementation of the API. # # (NOTE that when we clear the composite field in the parent, we actually # don't recursively clear down the tree. Instead, we just disconnect the # cleared composite from the tree.) + if api_implementation.Type() != 'python': + return self.assertTrue(old_composite_field is not composite_field) setattr(old_composite_field, scalar_field_name, new_val) self.assertTrue(not composite_field.HasField(scalar_field_name)) @@ -337,6 +348,8 @@ class ReflectionTest(unittest.TestCase): nested.bb = 23 def testDisconnectingNestedMessageBeforeSettingField(self): + if api_implementation.Type() != 'python': + return proto = unittest_pb2.TestAllTypes() nested = proto.optional_nested_message proto.ClearField('optional_nested_message') # Should disconnect from parent @@ -526,7 +539,6 @@ class ReflectionTest(unittest.TestCase): # proto.nonexistent_field = 23 should fail as well. self.assertRaises(AttributeError, setattr, proto, 'nonexistent_field', 23) - # TODO(robinson): Add type-safety check for enums. def testSingleScalarTypeSafety(self): proto = unittest_pb2.TestAllTypes() self.assertRaises(TypeError, setattr, proto, 'optional_int32', 1.1) @@ -538,7 +550,9 @@ class ReflectionTest(unittest.TestCase): def TestMinAndMaxIntegers(field_name, expected_min, expected_max): pb = unittest_pb2.TestAllTypes() setattr(pb, field_name, expected_min) + self.assertEqual(expected_min, getattr(pb, field_name)) setattr(pb, field_name, expected_max) + self.assertEqual(expected_max, getattr(pb, field_name)) self.assertRaises(ValueError, setattr, pb, field_name, expected_min - 1) self.assertRaises(ValueError, setattr, pb, field_name, expected_max + 1) @@ -546,7 +560,33 @@ class ReflectionTest(unittest.TestCase): TestMinAndMaxIntegers('optional_uint32', 0, 0xffffffff) TestMinAndMaxIntegers('optional_int64', -(1 << 63), (1 << 63) - 1) TestMinAndMaxIntegers('optional_uint64', 0, 0xffffffffffffffff) - TestMinAndMaxIntegers('optional_nested_enum', -(1 << 31), (1 << 31) - 1) + + pb = unittest_pb2.TestAllTypes() + pb.optional_nested_enum = 1 + self.assertEqual(1, pb.optional_nested_enum) + + # Invalid enum values. + pb.optional_nested_enum = 0 + self.assertEqual(0, pb.optional_nested_enum) + + bytes_size_before = pb.ByteSize() + + pb.optional_nested_enum = 4 + self.assertEqual(4, pb.optional_nested_enum) + + pb.optional_nested_enum = 0 + self.assertEqual(0, pb.optional_nested_enum) + + # Make sure that setting the same enum field doesn't just add unknown + # fields (but overwrites them). + self.assertEqual(bytes_size_before, pb.ByteSize()) + + # Is the invalid value preserved after serialization? + serialized = pb.SerializeToString() + pb2 = unittest_pb2.TestAllTypes() + pb2.ParseFromString(serialized) + self.assertEqual(0, pb2.optional_nested_enum) + self.assertEqual(pb, pb2) def testRepeatedScalarTypeSafety(self): proto = unittest_pb2.TestAllTypes() @@ -560,11 +600,19 @@ class ReflectionTest(unittest.TestCase): self.assertRaises(IndexError, proto.repeated_int32.__setitem__, 500, 23) self.assertRaises(TypeError, proto.repeated_int32.__setitem__, 0, 'abc') + # Repeated enums tests. + #proto.repeated_nested_enum.append(0) + def testSingleScalarGettersAndSetters(self): proto = unittest_pb2.TestAllTypes() self.assertEqual(0, proto.optional_int32) proto.optional_int32 = 1 self.assertEqual(1, proto.optional_int32) + + proto.optional_uint64 = 0xffffffffffff + self.assertEqual(0xffffffffffff, proto.optional_uint64) + proto.optional_uint64 = 0xffffffffffffffff + self.assertEqual(0xffffffffffffffff, proto.optional_uint64) # TODO(robinson): Test all other scalar field types. def testSingleScalarClearField(self): @@ -645,11 +693,38 @@ class ReflectionTest(unittest.TestCase): del proto.repeated_int32[2:] self.assertEqual([5, 35], proto.repeated_int32) + # Test extending. + proto.repeated_int32.extend([3, 13]) + self.assertEqual([5, 35, 3, 13], proto.repeated_int32) + # Test clearing. proto.ClearField('repeated_int32') self.assertTrue(not proto.repeated_int32) self.assertEqual(0, len(proto.repeated_int32)) + proto.repeated_int32.append(1) + self.assertEqual(1, proto.repeated_int32[-1]) + # Test assignment to a negative index. + proto.repeated_int32[-1] = 2 + self.assertEqual(2, proto.repeated_int32[-1]) + + # Test deletion at negative indices. + proto.repeated_int32[:] = [0, 1, 2, 3] + del proto.repeated_int32[-1] + self.assertEqual([0, 1, 2], proto.repeated_int32) + + del proto.repeated_int32[-2] + self.assertEqual([0, 2], proto.repeated_int32) + + self.assertRaises(IndexError, proto.repeated_int32.__delitem__, -3) + self.assertRaises(IndexError, proto.repeated_int32.__delitem__, 300) + + del proto.repeated_int32[-2:-1] + self.assertEqual([2], proto.repeated_int32) + + del proto.repeated_int32[100:10000] + self.assertEqual([2], proto.repeated_int32) + def testRepeatedScalarsRemove(self): proto = unittest_pb2.TestAllTypes() @@ -687,7 +762,7 @@ class ReflectionTest(unittest.TestCase): m1 = proto.repeated_nested_message.add() self.assertTrue(proto.repeated_nested_message) self.assertEqual(2, len(proto.repeated_nested_message)) - self.assertIs([m0, m1], proto.repeated_nested_message) + self.assertListsEqual([m0, m1], proto.repeated_nested_message) self.assertTrue(isinstance(m0, unittest_pb2.TestAllTypes.NestedMessage)) # Test out-of-bounds indices. @@ -706,32 +781,57 @@ class ReflectionTest(unittest.TestCase): m2 = proto.repeated_nested_message.add() m3 = proto.repeated_nested_message.add() m4 = proto.repeated_nested_message.add() - self.assertIs([m1, m2, m3], proto.repeated_nested_message[1:4]) - self.assertIs([m0, m1, m2, m3, m4], proto.repeated_nested_message[:]) + self.assertListsEqual( + [m1, m2, m3], proto.repeated_nested_message[1:4]) + self.assertListsEqual( + [m0, m1, m2, m3, m4], proto.repeated_nested_message[:]) + self.assertListsEqual( + [m0, m1], proto.repeated_nested_message[:2]) + self.assertListsEqual( + [m2, m3, m4], proto.repeated_nested_message[2:]) + self.assertEqual( + m0, proto.repeated_nested_message[0]) + self.assertListsEqual( + [m0], proto.repeated_nested_message[:1]) # Test that we can use the field as an iterator. result = [] for i in proto.repeated_nested_message: result.append(i) - self.assertIs([m0, m1, m2, m3, m4], result) + self.assertListsEqual([m0, m1, m2, m3, m4], result) # Test single deletion. del proto.repeated_nested_message[2] - self.assertIs([m0, m1, m3, m4], proto.repeated_nested_message) + self.assertListsEqual([m0, m1, m3, m4], proto.repeated_nested_message) # Test slice deletion. del proto.repeated_nested_message[2:] - self.assertIs([m0, m1], proto.repeated_nested_message) + self.assertListsEqual([m0, m1], proto.repeated_nested_message) + + # Test extending. + n1 = unittest_pb2.TestAllTypes.NestedMessage(bb=1) + n2 = unittest_pb2.TestAllTypes.NestedMessage(bb=2) + proto.repeated_nested_message.extend([n1,n2]) + self.assertEqual(4, len(proto.repeated_nested_message)) + self.assertEqual(n1, proto.repeated_nested_message[2]) + self.assertEqual(n2, proto.repeated_nested_message[3]) # Test clearing. proto.ClearField('repeated_nested_message') self.assertTrue(not proto.repeated_nested_message) self.assertEqual(0, len(proto.repeated_nested_message)) + # Test constructing an element while adding it. + proto.repeated_nested_message.add(bb=23) + self.assertEqual(1, len(proto.repeated_nested_message)) + self.assertEqual(23, proto.repeated_nested_message[0].bb) + def testHandWrittenReflection(self): - # TODO(robinson): We probably need a better way to specify - # protocol types by hand. But then again, this isn't something - # we expect many people to do. Hmm. + # Hand written extensions are only supported by the pure-Python + # implementation of the API. + if api_implementation.Type() != 'python': + return + FieldDescriptor = descriptor.FieldDescriptor foo_field_descriptor = FieldDescriptor( name='foo_field', full_name='MyProto.foo_field', @@ -894,7 +994,7 @@ class ReflectionTest(unittest.TestCase): self.assertTrue(not toplevel.HasField('submessage')) foreign = toplevel.submessage.Extensions[ more_extensions_pb2.repeated_message_extension].add() - self.assertTrue(foreign is toplevel.submessage.Extensions[ + self.assertEqual(foreign, toplevel.submessage.Extensions[ more_extensions_pb2.repeated_message_extension][0]) self.assertTrue(toplevel.HasField('submessage')) @@ -997,6 +1097,12 @@ class ReflectionTest(unittest.TestCase): self.assertEqual(123, proto2.repeated_nested_message[1].bb) self.assertEqual(321, proto2.repeated_nested_message[2].bb) + proto3 = unittest_pb2.TestAllTypes() + proto3.repeated_nested_message.MergeFrom(proto2.repeated_nested_message) + self.assertEqual(999, proto3.repeated_nested_message[0].bb) + self.assertEqual(123, proto3.repeated_nested_message[1].bb) + self.assertEqual(321, proto3.repeated_nested_message[2].bb) + def testMergeFromAllFields(self): # With all fields set. proto1 = unittest_pb2.TestAllTypes() @@ -1126,6 +1232,15 @@ class ReflectionTest(unittest.TestCase): self.assertEqual(2, proto1.optional_int32) self.assertEqual('important-text', proto1.optional_string) + def testCopyFromBadType(self): + # The python implementation doesn't raise an exception in this + # case. In theory it should. + if api_implementation.Type() == 'python': + return + proto1 = unittest_pb2.TestAllTypes() + proto2 = unittest_pb2.TestAllExtensions() + self.assertRaises(TypeError, proto1.CopyFrom, proto2) + def testClear(self): proto = unittest_pb2.TestAllTypes() test_util.SetAllFields(proto) @@ -1231,9 +1346,10 @@ class ReflectionTest(unittest.TestCase): proto.optional_string = str('Testing') self.assertEqual(proto.optional_string, unicode('Testing')) - # Values of type 'str' are also accepted as long as they can be encoded in - # UTF-8. - self.assertEqual(type(proto.optional_string), str) + if api_implementation.Type() == 'python': + # Values of type 'str' are also accepted as long as they can be + # encoded in UTF-8. + self.assertEqual(type(proto.optional_string), str) # Try to assign a 'str' value which contains bytes that aren't 7-bit ASCII. self.assertRaises(ValueError, @@ -1271,7 +1387,7 @@ class ReflectionTest(unittest.TestCase): # Check that the type_id is the same as the tag ID in the .proto file. self.assertEqual(raw.item[0].type_id, 1547769) - # Check the actually bytes on the wire. + # Check the actual bytes on the wire. self.assertTrue( raw.item[0].message.endswith(test_utf8_bytes)) message2.MergeFromString(raw.item[0].message) @@ -1279,10 +1395,23 @@ class ReflectionTest(unittest.TestCase): self.assertEqual(type(message2.str), unicode) self.assertEqual(message2.str, test_utf8) - # How about if the bytes on the wire aren't a valid UTF-8 encoded string. + # The pure Python API throws an exception on MergeFromString(), + # if any of the string fields of the message can't be UTF-8 decoded. + # The C++ implementation of the API has no way to check that on + # MergeFromString and thus has no way to throw the exception. + # + # The pure Python API always returns objects of type 'unicode' (UTF-8 + # encoded), or 'str' (in 7 bit ASCII). bytes = raw.item[0].message.replace( test_utf8_bytes, len(test_utf8_bytes) * '\xff') - self.assertRaises(UnicodeDecodeError, message2.MergeFromString, bytes) + + unicode_decode_failed = False + try: + message2.MergeFromString(bytes) + except UnicodeDecodeError, e: + unicode_decode_failed = True + string_field = message2.str + self.assertTrue(unicode_decode_failed or type(string_field) == str) def testEmptyNestedMessage(self): proto = unittest_pb2.TestAllTypes() @@ -1325,6 +1454,9 @@ class TestAllTypesEqualityTest(unittest.TestCase): self.first_proto = unittest_pb2.TestAllTypes() self.second_proto = unittest_pb2.TestAllTypes() + def testNotHashable(self): + self.assertRaises(TypeError, hash, self.first_proto) + def testSelfEquality(self): self.assertEqual(self.first_proto, self.first_proto) @@ -1342,6 +1474,9 @@ class FullProtosEqualityTest(unittest.TestCase): test_util.SetAllFields(self.first_proto) test_util.SetAllFields(self.second_proto) + def testNotHashable(self): + self.assertRaises(TypeError, hash, self.first_proto) + def testNoneNotEqual(self): self.assertNotEqual(self.first_proto, None) self.assertNotEqual(None, self.second_proto) @@ -1410,9 +1545,6 @@ class FullProtosEqualityTest(unittest.TestCase): self.first_proto.ClearField('optional_nested_message') self.second_proto.optional_nested_message.ClearField('bb') self.assertNotEqual(self.first_proto, self.second_proto) - # TODO(robinson): Replace next two lines with method - # to set the "has" bit without changing the value, - # if/when such a method exists. self.first_proto.optional_nested_message.bb = 0 self.first_proto.optional_nested_message.ClearField('bb') self.assertEqual(self.first_proto, self.second_proto) @@ -1477,6 +1609,14 @@ class ByteSizeTest(unittest.TestCase): def testEmptyMessage(self): self.assertEqual(0, self.proto.ByteSize()) + def testSizedOnKwargs(self): + # Use a separate message to ensure testing right after creation. + proto = unittest_pb2.TestAllTypes() + self.assertEqual(0, proto.ByteSize()) + proto_kwargs = unittest_pb2.TestAllTypes(optional_int64 = 1) + # One byte for the tag, one to encode varint 1. + self.assertEqual(2, proto_kwargs.ByteSize()) + def testVarints(self): def Test(i, expected_varint_size): self.proto.Clear() @@ -1668,10 +1808,13 @@ class ByteSizeTest(unittest.TestCase): self.assertEqual(3, self.proto.ByteSize()) self.proto.ClearField('optional_foreign_message') self.assertEqual(0, self.proto.ByteSize()) - child = self.proto.optional_foreign_message - self.proto.ClearField('optional_foreign_message') - child.c = 128 - self.assertEqual(0, self.proto.ByteSize()) + + if api_implementation.Type() == 'python': + # This is only possible in pure-Python implementation of the API. + child = self.proto.optional_foreign_message + self.proto.ClearField('optional_foreign_message') + child.c = 128 + self.assertEqual(0, self.proto.ByteSize()) # Test within extension. extension = more_extensions_pb2.optional_message_extension @@ -1737,7 +1880,6 @@ class ByteSizeTest(unittest.TestCase): self.assertEqual(19, self.packed_extended_proto.ByteSize()) -# TODO(robinson): We need cross-language serialization consistency tests. # Issues to be sure to cover include: # * Handling of unrecognized tags ("uninterpreted_bytes"). # * Handling of MessageSets. @@ -1792,6 +1934,10 @@ class SerializationTest(unittest.TestCase): self.assertEqual(first_proto, second_proto) def testParseTruncated(self): + # This test is only applicable for the Python implementation of the API. + if api_implementation.Type() != 'python': + return + first_proto = unittest_pb2.TestAllTypes() test_util.SetAllFields(first_proto) serialized = first_proto.SerializeToString() diff --git a/third_party/protobuf/python/google/protobuf/internal/text_format_test.py b/third_party/protobuf/python/google/protobuf/internal/text_format_test.py index e0991cb..73d97d1 100755 --- a/third_party/protobuf/python/google/protobuf/internal/text_format_test.py +++ b/third_party/protobuf/python/google/protobuf/internal/text_format_test.py @@ -35,6 +35,7 @@ __author__ = 'kenton@google.com (Kenton Varda)' import difflib +import re import unittest from google.protobuf import text_format @@ -95,12 +96,13 @@ class TextFormatTest(unittest.TestCase): def testPrintExotic(self): message = unittest_pb2.TestAllTypes() - message.repeated_int64.append(-9223372036854775808); - message.repeated_uint64.append(18446744073709551615); - message.repeated_double.append(123.456); - message.repeated_double.append(1.23e22); - message.repeated_double.append(1.23e-18); - message.repeated_string.append('\000\001\a\b\f\n\r\t\v\\\'\"'); + message.repeated_int64.append(-9223372036854775808) + message.repeated_uint64.append(18446744073709551615) + message.repeated_double.append(123.456) + message.repeated_double.append(1.23e22) + message.repeated_double.append(1.23e-18) + message.repeated_string.append('\000\001\a\b\f\n\r\t\v\\\'"') + message.repeated_string.append(u'\u00fc\ua71f') self.CompareToGoldenText( self.RemoveRedundantZeros(text_format.MessageToString(message)), 'repeated_int64: -9223372036854775808\n' @@ -109,7 +111,106 @@ class TextFormatTest(unittest.TestCase): 'repeated_double: 1.23e+22\n' 'repeated_double: 1.23e-18\n' 'repeated_string: ' - '\"\\000\\001\\007\\010\\014\\n\\r\\t\\013\\\\\\\'\\\"\"\n') + '"\\000\\001\\007\\010\\014\\n\\r\\t\\013\\\\\\\'\\""\n' + 'repeated_string: "\\303\\274\\352\\234\\237"\n') + + def testPrintNestedMessageAsOneLine(self): + message = unittest_pb2.TestAllTypes() + msg = message.repeated_nested_message.add() + msg.bb = 42; + self.CompareToGoldenText( + text_format.MessageToString(message, as_one_line=True), + 'repeated_nested_message { bb: 42 }') + + def testPrintRepeatedFieldsAsOneLine(self): + message = unittest_pb2.TestAllTypes() + message.repeated_int32.append(1) + message.repeated_int32.append(1) + message.repeated_int32.append(3) + message.repeated_string.append("Google") + message.repeated_string.append("Zurich") + self.CompareToGoldenText( + text_format.MessageToString(message, as_one_line=True), + 'repeated_int32: 1 repeated_int32: 1 repeated_int32: 3 ' + 'repeated_string: "Google" repeated_string: "Zurich"') + + def testPrintNestedNewLineInStringAsOneLine(self): + message = unittest_pb2.TestAllTypes() + message.optional_string = "a\nnew\nline" + self.CompareToGoldenText( + text_format.MessageToString(message, as_one_line=True), + 'optional_string: "a\\nnew\\nline"') + + def testPrintMessageSetAsOneLine(self): + message = unittest_mset_pb2.TestMessageSetContainer() + ext1 = unittest_mset_pb2.TestMessageSetExtension1.message_set_extension + ext2 = unittest_mset_pb2.TestMessageSetExtension2.message_set_extension + message.message_set.Extensions[ext1].i = 23 + message.message_set.Extensions[ext2].str = 'foo' + self.CompareToGoldenText( + text_format.MessageToString(message, as_one_line=True), + 'message_set {' + ' [protobuf_unittest.TestMessageSetExtension1] {' + ' i: 23' + ' }' + ' [protobuf_unittest.TestMessageSetExtension2] {' + ' str: \"foo\"' + ' }' + ' }') + + def testPrintExoticAsOneLine(self): + message = unittest_pb2.TestAllTypes() + message.repeated_int64.append(-9223372036854775808) + message.repeated_uint64.append(18446744073709551615) + message.repeated_double.append(123.456) + message.repeated_double.append(1.23e22) + message.repeated_double.append(1.23e-18) + message.repeated_string.append('\000\001\a\b\f\n\r\t\v\\\'"') + message.repeated_string.append(u'\u00fc\ua71f') + self.CompareToGoldenText( + self.RemoveRedundantZeros( + text_format.MessageToString(message, as_one_line=True)), + 'repeated_int64: -9223372036854775808' + ' repeated_uint64: 18446744073709551615' + ' repeated_double: 123.456' + ' repeated_double: 1.23e+22' + ' repeated_double: 1.23e-18' + ' repeated_string: ' + '"\\000\\001\\007\\010\\014\\n\\r\\t\\013\\\\\\\'\\""' + ' repeated_string: "\\303\\274\\352\\234\\237"') + + def testRoundTripExoticAsOneLine(self): + message = unittest_pb2.TestAllTypes() + message.repeated_int64.append(-9223372036854775808) + message.repeated_uint64.append(18446744073709551615) + message.repeated_double.append(123.456) + message.repeated_double.append(1.23e22) + message.repeated_double.append(1.23e-18) + message.repeated_string.append('\000\001\a\b\f\n\r\t\v\\\'"') + message.repeated_string.append(u'\u00fc\ua71f') + + # Test as_utf8 = False. + wire_text = text_format.MessageToString( + message, as_one_line=True, as_utf8=False) + parsed_message = unittest_pb2.TestAllTypes() + text_format.Merge(wire_text, parsed_message) + self.assertEquals(message, parsed_message) + + # Test as_utf8 = True. + wire_text = text_format.MessageToString( + message, as_one_line=True, as_utf8=True) + parsed_message = unittest_pb2.TestAllTypes() + text_format.Merge(wire_text, parsed_message) + self.assertEquals(message, parsed_message) + + def testPrintRawUtf8String(self): + message = unittest_pb2.TestAllTypes() + message.repeated_string.append(u'\u00fc\ua71f') + text = text_format.MessageToString(message, as_utf8 = True) + self.CompareToGoldenText(text, 'repeated_string: "\303\274\352\234\237"\n') + parsed_message = unittest_pb2.TestAllTypes() + text_format.Merge(text, parsed_message) + self.assertEquals(message, parsed_message) def testMessageToString(self): message = unittest_pb2.ForeignMessage() @@ -119,8 +220,12 @@ class TextFormatTest(unittest.TestCase): def RemoveRedundantZeros(self, text): # Some platforms print 1e+5 as 1e+005. This is fine, but we need to remove # these zeros in order to match the golden file. - return text.replace('e+0','e+').replace('e+0','e+') \ + text = text.replace('e+0','e+').replace('e+0','e+') \ .replace('e-0','e-').replace('e-0','e-') + # Floating point fields are printed with .0 suffix even if they are + # actualy integer numbers. + text = re.compile('\.0$', re.MULTILINE).sub('', text) + return text def testMergeGolden(self): golden_text = '\n'.join(self.ReadGolden('text_format_unittest_data.txt')) @@ -191,8 +296,11 @@ class TextFormatTest(unittest.TestCase): 'repeated_double: 1.23e+22\n' 'repeated_double: 1.23e-18\n' 'repeated_string: \n' - '\"\\000\\001\\007\\010\\014\\n\\r\\t\\013\\\\\\\'\\\"\"\n' - 'repeated_string: "foo" \'corge\' "grault"') + '"\\000\\001\\007\\010\\014\\n\\r\\t\\013\\\\\\\'\\""\n' + 'repeated_string: "foo" \'corge\' "grault"\n' + 'repeated_string: "\\303\\274\\352\\234\\237"\n' + 'repeated_string: "\\xc3\\xbc"\n' + 'repeated_string: "\xc3\xbc"\n') text_format.Merge(text, message) self.assertEqual(-9223372036854775808, message.repeated_int64[0]) @@ -201,8 +309,30 @@ class TextFormatTest(unittest.TestCase): self.assertEqual(1.23e22, message.repeated_double[1]) self.assertEqual(1.23e-18, message.repeated_double[2]) self.assertEqual( - '\000\001\a\b\f\n\r\t\v\\\'\"', message.repeated_string[0]) + '\000\001\a\b\f\n\r\t\v\\\'"', message.repeated_string[0]) self.assertEqual('foocorgegrault', message.repeated_string[1]) + self.assertEqual(u'\u00fc\ua71f', message.repeated_string[2]) + self.assertEqual(u'\u00fc', message.repeated_string[3]) + + def testMergeEmptyText(self): + message = unittest_pb2.TestAllTypes() + text = '' + text_format.Merge(text, message) + self.assertEquals(unittest_pb2.TestAllTypes(), message) + + def testMergeInvalidUtf8(self): + message = unittest_pb2.TestAllTypes() + text = 'repeated_string: "\\xc3\\xc3"' + self.assertRaises(text_format.ParseError, text_format.Merge, text, message) + + def testMergeSingleWord(self): + message = unittest_pb2.TestAllTypes() + text = 'foo' + self.assertRaisesWithMessage( + text_format.ParseError, + ('1:1 : Message type "protobuf_unittest.TestAllTypes" has no field named ' + '"foo".'), + text_format.Merge, text, message) def testMergeUnknownField(self): message = unittest_pb2.TestAllTypes() @@ -297,7 +427,8 @@ class TokenizerTest(unittest.TestCase): 'identifiER_4 : 1.1e+2 ID5:-0.23 ID6:\'aaaa\\\'bbbb\'\n' 'ID7 : "aa\\"bb"\n\n\n\n ID8: {A:inf B:-inf C:true D:false}\n' 'ID9: 22 ID10: -111111111111111111 ID11: -22\n' - 'ID12: 2222222222222222222') + 'ID12: 2222222222222222222 ' + 'false_bool: 0 true_BOOL:t \n true_bool1: 1 false_BOOL1:f ' ) tokenizer = text_format._Tokenizer(text) methods = [(tokenizer.ConsumeIdentifier, 'identifier1'), ':', @@ -347,7 +478,19 @@ class TokenizerTest(unittest.TestCase): (tokenizer.ConsumeInt32, -22), (tokenizer.ConsumeIdentifier, 'ID12'), ':', - (tokenizer.ConsumeUint64, 2222222222222222222)] + (tokenizer.ConsumeUint64, 2222222222222222222), + (tokenizer.ConsumeIdentifier, 'false_bool'), + ':', + (tokenizer.ConsumeBool, False), + (tokenizer.ConsumeIdentifier, 'true_BOOL'), + ':', + (tokenizer.ConsumeBool, True), + (tokenizer.ConsumeIdentifier, 'true_bool1'), + ':', + (tokenizer.ConsumeBool, True), + (tokenizer.ConsumeIdentifier, 'false_BOOL1'), + ':', + (tokenizer.ConsumeBool, False)] i = 0 while not tokenizer.AtEnd(): diff --git a/third_party/protobuf/python/google/protobuf/message.py b/third_party/protobuf/python/google/protobuf/message.py index f839847..6f19f85 100755 --- a/third_party/protobuf/python/google/protobuf/message.py +++ b/third_party/protobuf/python/google/protobuf/message.py @@ -67,6 +67,11 @@ class Message(object): DESCRIPTOR = None + def __deepcopy__(self, memo=None): + clone = type(self)() + clone.MergeFrom(self) + return clone + def __eq__(self, other_msg): raise NotImplementedError @@ -74,9 +79,15 @@ class Message(object): # Can't just say self != other_msg, since that would infinitely recurse. :) return not self == other_msg + def __hash__(self): + raise TypeError('unhashable object') + def __str__(self): raise NotImplementedError + def __unicode__(self): + raise NotImplementedError + def MergeFrom(self, other_msg): """Merges the contents of the specified message into current message. @@ -215,6 +226,9 @@ class Message(object): raise NotImplementedError def HasField(self, field_name): + """Checks if a certain field is set for the message. Note if the + field_name is not defined in the message descriptor, ValueError will be + raised.""" raise NotImplementedError def ClearField(self, field_name): diff --git a/third_party/protobuf/python/google/protobuf/pyext/python-proto2.cc b/third_party/protobuf/python/google/protobuf/pyext/python-proto2.cc new file mode 100644 index 0000000..f2799e6 --- /dev/null +++ b/third_party/protobuf/python/google/protobuf/pyext/python-proto2.cc @@ -0,0 +1,1658 @@ +// 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: petar@google.com (Petar Petrov) + +#include <Python.h> +#include <map> +#include <string> +#include <vector> + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/pyext/python_descriptor.h> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/dynamic_message.h> +#include <google/protobuf/message.h> +#include <google/protobuf/unknown_field_set.h> +#include <google/protobuf/pyext/python_protobuf.h> + +/* Is 64bit */ +#define IS_64BIT (SIZEOF_LONG == 8) + +#define FIELD_BELONGS_TO_MESSAGE(field_descriptor, message) \ + ((message)->GetDescriptor() == (field_descriptor)->containing_type()) + +#define FIELD_IS_REPEATED(field_descriptor) \ + ((field_descriptor)->label() == google::protobuf::FieldDescriptor::LABEL_REPEATED) + +#define GOOGLE_CHECK_GET_INT32(arg, value) \ + int32 value; \ + if (!CheckAndGetInteger(arg, &value, kint32min_py, kint32max_py)) { \ + return NULL; \ + } + +#define GOOGLE_CHECK_GET_INT64(arg, value) \ + int64 value; \ + if (!CheckAndGetInteger(arg, &value, kint64min_py, kint64max_py)) { \ + return NULL; \ + } + +#define GOOGLE_CHECK_GET_UINT32(arg, value) \ + uint32 value; \ + if (!CheckAndGetInteger(arg, &value, kPythonZero, kuint32max_py)) { \ + return NULL; \ + } + +#define GOOGLE_CHECK_GET_UINT64(arg, value) \ + uint64 value; \ + if (!CheckAndGetInteger(arg, &value, kPythonZero, kuint64max_py)) { \ + return NULL; \ + } + +#define GOOGLE_CHECK_GET_FLOAT(arg, value) \ + float value; \ + if (!CheckAndGetFloat(arg, &value)) { \ + return NULL; \ + } \ + +#define GOOGLE_CHECK_GET_DOUBLE(arg, value) \ + double value; \ + if (!CheckAndGetDouble(arg, &value)) { \ + return NULL; \ + } + +#define GOOGLE_CHECK_GET_BOOL(arg, value) \ + bool value; \ + if (!CheckAndGetBool(arg, &value)) { \ + return NULL; \ + } + +#define C(str) const_cast<char*>(str) + +// --- Globals: + +// Constants used for integer type range checking. +static PyObject* kPythonZero; +static PyObject* kint32min_py; +static PyObject* kint32max_py; +static PyObject* kuint32max_py; +static PyObject* kint64min_py; +static PyObject* kint64max_py; +static PyObject* kuint64max_py; + +namespace google { +namespace protobuf { +namespace python { + +// --- Support Routines: + +static void AddConstants(PyObject* module) { + struct NameValue { + char* name; + int32 value; + } constants[] = { + // Labels: + {"LABEL_OPTIONAL", google::protobuf::FieldDescriptor::LABEL_OPTIONAL}, + {"LABEL_REQUIRED", google::protobuf::FieldDescriptor::LABEL_REQUIRED}, + {"LABEL_REPEATED", google::protobuf::FieldDescriptor::LABEL_REPEATED}, + // CPP types: + {"CPPTYPE_MESSAGE", google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE}, + // Field Types: + {"TYPE_MESSAGE", google::protobuf::FieldDescriptor::TYPE_MESSAGE}, + // End. + {NULL, 0} + }; + + for (NameValue* constant = constants; + constant->name != NULL; constant++) { + PyModule_AddIntConstant(module, constant->name, constant->value); + } +} + +// --- CMessage Custom Type: + +// ------ Type Forward Declaration: + +struct CMessage; +struct CMessage_Type; + +static void CMessageDealloc(CMessage* self); +static int CMessageInit(CMessage* self, PyObject *args, PyObject *kwds); +static PyObject* CMessageStr(CMessage* self); + +static PyObject* CMessage_AddMessage(CMessage* self, PyObject* args); +static PyObject* CMessage_AddRepeatedScalar(CMessage* self, PyObject* args); +static PyObject* CMessage_AssignRepeatedScalar(CMessage* self, PyObject* args); +static PyObject* CMessage_ByteSize(CMessage* self, PyObject* args); +static PyObject* CMessage_Clear(CMessage* self, PyObject* args); +static PyObject* CMessage_ClearField(CMessage* self, PyObject* args); +static PyObject* CMessage_ClearFieldByDescriptor( + CMessage* self, PyObject* args); +static PyObject* CMessage_CopyFrom(CMessage* self, PyObject* args); +static PyObject* CMessage_DebugString(CMessage* self, PyObject* args); +static PyObject* CMessage_DeleteRepeatedField(CMessage* self, PyObject* args); +static PyObject* CMessage_Equals(CMessage* self, PyObject* args); +static PyObject* CMessage_FieldLength(CMessage* self, PyObject* args); +static PyObject* CMessage_FindInitializationErrors(CMessage* self); +static PyObject* CMessage_GetRepeatedMessage(CMessage* self, PyObject* args); +static PyObject* CMessage_GetRepeatedScalar(CMessage* self, PyObject* args); +static PyObject* CMessage_GetScalar(CMessage* self, PyObject* args); +static PyObject* CMessage_HasField(CMessage* self, PyObject* args); +static PyObject* CMessage_HasFieldByDescriptor(CMessage* self, PyObject* args); +static PyObject* CMessage_IsInitialized(CMessage* self, PyObject* args); +static PyObject* CMessage_ListFields(CMessage* self, PyObject* args); +static PyObject* CMessage_MergeFrom(CMessage* self, PyObject* args); +static PyObject* CMessage_MergeFromString(CMessage* self, PyObject* args); +static PyObject* CMessage_MutableMessage(CMessage* self, PyObject* args); +static PyObject* CMessage_NewSubMessage(CMessage* self, PyObject* args); +static PyObject* CMessage_SetScalar(CMessage* self, PyObject* args); +static PyObject* CMessage_SerializePartialToString( + CMessage* self, PyObject* args); +static PyObject* CMessage_SerializeToString(CMessage* self, PyObject* args); +static PyObject* CMessage_SetInParent(CMessage* self, PyObject* args); +static PyObject* CMessage_SwapRepeatedFieldElements( + CMessage* self, PyObject* args); + +// ------ Object Definition: + +typedef struct CMessage { + PyObject_HEAD + + struct CMessage* parent; // NULL if wasn't created from another message. + CFieldDescriptor* parent_field; + const char* full_name; + google::protobuf::Message* message; + bool free_message; + bool read_only; +} CMessage; + +// ------ Method Table: + +#define CMETHOD(name, args, doc) \ + { C(#name), (PyCFunction)CMessage_##name, args, C(doc) } +static PyMethodDef CMessageMethods[] = { + CMETHOD(AddMessage, METH_O, + "Adds a new message to a repeated composite field."), + CMETHOD(AddRepeatedScalar, METH_VARARGS, + "Adds a scalar to a repeated scalar field."), + CMETHOD(AssignRepeatedScalar, METH_VARARGS, + "Clears and sets the values of a repeated scalar field."), + CMETHOD(ByteSize, METH_NOARGS, + "Returns the size of the message in bytes."), + CMETHOD(Clear, METH_NOARGS, + "Clears a protocol message."), + CMETHOD(ClearField, METH_O, + "Clears a protocol message field by name."), + CMETHOD(ClearFieldByDescriptor, METH_O, + "Clears a protocol message field by descriptor."), + CMETHOD(CopyFrom, METH_O, + "Copies a protocol message into the current message."), + CMETHOD(DebugString, METH_NOARGS, + "Returns the debug string of a protocol message."), + CMETHOD(DeleteRepeatedField, METH_VARARGS, + "Deletes a slice of values from a repeated field."), + CMETHOD(Equals, METH_O, + "Checks if two protocol messages are equal (by identity)."), + CMETHOD(FieldLength, METH_O, + "Returns the number of elements in a repeated field."), + CMETHOD(FindInitializationErrors, METH_NOARGS, + "Returns the initialization errors of a message."), + CMETHOD(GetRepeatedMessage, METH_VARARGS, + "Returns a message from a repeated composite field."), + CMETHOD(GetRepeatedScalar, METH_VARARGS, + "Returns a scalar value from a repeated scalar field."), + CMETHOD(GetScalar, METH_O, + "Returns the scalar value of a field."), + CMETHOD(HasField, METH_O, + "Checks if a message field is set."), + CMETHOD(HasFieldByDescriptor, METH_O, + "Checks if a message field is set by given its descriptor"), + CMETHOD(IsInitialized, METH_NOARGS, + "Checks if all required fields of a protocol message are set."), + CMETHOD(ListFields, METH_NOARGS, + "Lists all set fields of a message."), + CMETHOD(MergeFrom, METH_O, + "Merges a protocol message into the current message."), + CMETHOD(MergeFromString, METH_O, + "Merges a serialized message into the current message."), + CMETHOD(MutableMessage, METH_O, + "Returns a new instance of a nested protocol message."), + CMETHOD(NewSubMessage, METH_O, + "Creates and returns a python message given the descriptor of a " + "composite field of the current message."), + CMETHOD(SetScalar, METH_VARARGS, + "Sets the value of a singular scalar field."), + CMETHOD(SerializePartialToString, METH_VARARGS, + "Serializes the message to a string, even if it isn't initialized."), + CMETHOD(SerializeToString, METH_NOARGS, + "Serializes the message to a string, only for initialized messages."), + CMETHOD(SetInParent, METH_NOARGS, + "Sets the has bit of the given field in its parent message."), + CMETHOD(SwapRepeatedFieldElements, METH_VARARGS, + "Swaps the elements in two positions in a repeated field."), + { NULL, NULL } +}; +#undef CMETHOD + +static PyMemberDef CMessageMembers[] = { + { C("full_name"), T_STRING, offsetof(CMessage, full_name), 0, "Full name" }, + { NULL } +}; + +// ------ Type Definition: + +// The definition for the type object that captures the type of CMessage +// in Python. +PyTypeObject CMessage_Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, + C("google3.net.google.protobuf.python.internal." + "_net_proto2___python." + "CMessage"), // tp_name + sizeof(CMessage), // tp_basicsize + 0, // tp_itemsize + (destructor)CMessageDealloc, // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + 0, // tp_repr + 0, // tp_as_number + 0, // tp_as_sequence + 0, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + (reprfunc)CMessageStr, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + C("A ProtocolMessage"), // tp_doc + 0, // tp_traverse + 0, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + CMessageMethods, // tp_methods + CMessageMembers, // tp_members + 0, // tp_getset + 0, // tp_base + 0, // tp_dict + 0, // tp_descr_get + 0, // tp_descr_set + 0, // tp_dictoffset + (initproc)CMessageInit, // tp_init + PyType_GenericAlloc, // tp_alloc + PyType_GenericNew, // tp_new + PyObject_Del, // tp_free +}; + +// ------ Helper Functions: + +static void FormatTypeError(PyObject* arg, char* expected_types) { + PyObject* s = PyObject_Str(PyObject_Type(arg)); + PyObject* repr = PyObject_Repr(PyObject_Type(arg)); + PyErr_Format(PyExc_TypeError, + "%.100s has type %.100s, but expected one of: %s", + PyString_AS_STRING(repr), + PyString_AS_STRING(s), + expected_types); + Py_DECREF(s); + Py_DECREF(repr); +} + +template <class T> +static bool CheckAndGetInteger( + PyObject* arg, T* value, PyObject* min, PyObject* max) { + bool is_long = PyLong_Check(arg); + if (!PyInt_Check(arg) && !is_long) { + FormatTypeError(arg, "int, long"); + return false; + } + + if (PyObject_Compare(min, arg) > 0 || PyObject_Compare(max, arg) < 0) { + PyObject* s = PyObject_Str(arg); + PyErr_Format(PyExc_ValueError, + "Value out of range: %s", + PyString_AS_STRING(s)); + Py_DECREF(s); + return false; + } + if (is_long) { + if (min == kPythonZero) { + *value = static_cast<T>(PyLong_AsUnsignedLongLong(arg)); + } else { + *value = static_cast<T>(PyLong_AsLongLong(arg)); + } + } else { + *value = static_cast<T>(PyInt_AsLong(arg)); + } + return true; +} + +static bool CheckAndGetDouble(PyObject* arg, double* value) { + if (!PyInt_Check(arg) && !PyLong_Check(arg) && + !PyFloat_Check(arg)) { + FormatTypeError(arg, "int, long, float"); + return false; + } + *value = PyFloat_AsDouble(arg); + return true; +} + +static bool CheckAndGetFloat(PyObject* arg, float* value) { + double double_value; + if (!CheckAndGetDouble(arg, &double_value)) { + return false; + } + *value = static_cast<float>(double_value); + return true; +} + +static bool CheckAndGetBool(PyObject* arg, bool* value) { + if (!PyInt_Check(arg) && !PyBool_Check(arg) && !PyLong_Check(arg)) { + FormatTypeError(arg, "int, long, bool"); + return false; + } + *value = static_cast<bool>(PyInt_AsLong(arg)); + return true; +} + +google::protobuf::DynamicMessageFactory* global_message_factory = NULL; +static const google::protobuf::Message* CreateMessage(const char* message_type) { + string message_name(message_type); + const google::protobuf::Descriptor* descriptor = + GetDescriptorPool()->FindMessageTypeByName(message_name); + if (descriptor == NULL) { + return NULL; + } + return global_message_factory->GetPrototype(descriptor); +} + +static bool CheckAndSetString( + PyObject* arg, google::protobuf::Message* message, + const google::protobuf::FieldDescriptor* descriptor, + const google::protobuf::Reflection* reflection, + bool append, + int index) { + GOOGLE_DCHECK(descriptor->type() == google::protobuf::FieldDescriptor::TYPE_STRING || + descriptor->type() == google::protobuf::FieldDescriptor::TYPE_BYTES); + if (descriptor->type() == google::protobuf::FieldDescriptor::TYPE_STRING) { + if (!PyString_Check(arg) && !PyUnicode_Check(arg)) { + FormatTypeError(arg, "str, unicode"); + return false; + } + + if (PyString_Check(arg)) { + PyObject* unicode = PyUnicode_FromEncodedObject(arg, "ascii", NULL); + if (unicode == NULL) { + PyObject* repr = PyObject_Repr(arg); + PyErr_Format(PyExc_ValueError, + "%s has type str, but isn't in 7-bit ASCII " + "encoding. Non-ASCII strings must be converted to " + "unicode objects before being added.", + PyString_AS_STRING(repr)); + Py_DECREF(repr); + return false; + } else { + Py_DECREF(unicode); + } + } + } else if (!PyString_Check(arg)) { + FormatTypeError(arg, "str"); + return false; + } + + PyObject* encoded_string = NULL; + if (descriptor->type() == google::protobuf::FieldDescriptor::TYPE_STRING) { + if (PyString_Check(arg)) { + encoded_string = PyString_AsEncodedObject(arg, "utf-8", NULL); + } else { + encoded_string = PyUnicode_AsEncodedObject(arg, "utf-8", NULL); + } + } else { + // In this case field type is "bytes". + encoded_string = arg; + Py_INCREF(encoded_string); + } + + if (encoded_string == NULL) { + return false; + } + + char* value; + Py_ssize_t value_len; + if (PyString_AsStringAndSize(encoded_string, &value, &value_len) < 0) { + Py_DECREF(encoded_string); + return false; + } + + string value_string(value, value_len); + if (append) { + reflection->AddString(message, descriptor, value_string); + } else if (index < 0) { + reflection->SetString(message, descriptor, value_string); + } else { + reflection->SetRepeatedString(message, descriptor, index, value_string); + } + Py_DECREF(encoded_string); + return true; +} + +static PyObject* ToStringObject( + const google::protobuf::FieldDescriptor* descriptor, string value) { + if (descriptor->type() != google::protobuf::FieldDescriptor::TYPE_STRING) { + return PyString_FromStringAndSize(value.c_str(), value.length()); + } + + PyObject* result = PyUnicode_DecodeUTF8(value.c_str(), value.length(), NULL); + // If the string can't be decoded in UTF-8, just return a string object that + // contains the raw bytes. This can't happen if the value was assigned using + // the members of the Python message object, but can happen if the values were + // parsed from the wire (binary). + if (result == NULL) { + PyErr_Clear(); + result = PyString_FromStringAndSize(value.c_str(), value.length()); + } + return result; +} + +static void AssureWritable(CMessage* self) { + if (self == NULL || + self->parent == NULL || + self->parent_field == NULL) { + return; + } + + if (!self->read_only) { + return; + } + + AssureWritable(self->parent); + + google::protobuf::Message* message = self->parent->message; + const google::protobuf::Reflection* reflection = message->GetReflection(); + self->message = reflection->MutableMessage( + message, self->parent_field->descriptor, global_message_factory); + self->read_only = false; + self->parent = NULL; + self->parent_field = NULL; +} + +static PyObject* InternalGetScalar( + google::protobuf::Message* message, + const google::protobuf::FieldDescriptor* field_descriptor) { + const google::protobuf::Reflection* reflection = message->GetReflection(); + + if (!FIELD_BELONGS_TO_MESSAGE(field_descriptor, message)) { + PyErr_SetString( + PyExc_KeyError, "Field does not belong to message!"); + return NULL; + } + + PyObject* result = NULL; + switch (field_descriptor->cpp_type()) { + case google::protobuf::FieldDescriptor::CPPTYPE_INT32: { + int32 value = reflection->GetInt32(*message, field_descriptor); + result = PyInt_FromLong(value); + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_INT64: { + int64 value = reflection->GetInt64(*message, field_descriptor); +#if IS_64BIT + result = PyInt_FromLong(value); +#else + result = PyLong_FromLongLong(value); +#endif + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_UINT32: { + uint32 value = reflection->GetUInt32(*message, field_descriptor); +#if IS_64BIT + result = PyInt_FromLong(value); +#else + result = PyLong_FromLongLong(value); +#endif + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_UINT64: { + uint64 value = reflection->GetUInt64(*message, field_descriptor); +#if IS_64BIT + if (value <= static_cast<uint64>(kint64max)) { + result = PyInt_FromLong(static_cast<uint64>(value)); + } +#else + if (value <= static_cast<uint32>(kint32max)) { + result = PyInt_FromLong(static_cast<uint32>(value)); + } +#endif + else { // NOLINT + result = PyLong_FromUnsignedLongLong(value); + } + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT: { + float value = reflection->GetFloat(*message, field_descriptor); + result = PyFloat_FromDouble(value); + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE: { + double value = reflection->GetDouble(*message, field_descriptor); + result = PyFloat_FromDouble(value); + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_BOOL: { + bool value = reflection->GetBool(*message, field_descriptor); + result = PyBool_FromLong(value); + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_STRING: { + string value = reflection->GetString(*message, field_descriptor); + result = ToStringObject(field_descriptor, value); + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_ENUM: { + if (!message->GetReflection()->HasField(*message, field_descriptor)) { + // Look for the value in the unknown fields. + google::protobuf::UnknownFieldSet* unknown_field_set = + message->GetReflection()->MutableUnknownFields(message); + for (int i = 0; i < unknown_field_set->field_count(); ++i) { + if (unknown_field_set->field(i).number() == + field_descriptor->number()) { + result = PyInt_FromLong(unknown_field_set->field(i).varint()); + break; + } + } + } + + if (result == NULL) { + const google::protobuf::EnumValueDescriptor* enum_value = + message->GetReflection()->GetEnum(*message, field_descriptor); + result = PyInt_FromLong(enum_value->number()); + } + break; + } + default: + PyErr_Format( + PyExc_SystemError, "Getting a value from a field of unknown type %d", + field_descriptor->cpp_type()); + } + + return result; +} + +static PyObject* InternalSetScalar( + google::protobuf::Message* message, const google::protobuf::FieldDescriptor* field_descriptor, + PyObject* arg) { + const google::protobuf::Reflection* reflection = message->GetReflection(); + + if (!FIELD_BELONGS_TO_MESSAGE(field_descriptor, message)) { + PyErr_SetString( + PyExc_KeyError, "Field does not belong to message!"); + return NULL; + } + + switch (field_descriptor->cpp_type()) { + case google::protobuf::FieldDescriptor::CPPTYPE_INT32: { + GOOGLE_CHECK_GET_INT32(arg, value); + reflection->SetInt32(message, field_descriptor, value); + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_INT64: { + GOOGLE_CHECK_GET_INT64(arg, value); + reflection->SetInt64(message, field_descriptor, value); + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_UINT32: { + GOOGLE_CHECK_GET_UINT32(arg, value); + reflection->SetUInt32(message, field_descriptor, value); + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_UINT64: { + GOOGLE_CHECK_GET_UINT64(arg, value); + reflection->SetUInt64(message, field_descriptor, value); + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT: { + GOOGLE_CHECK_GET_FLOAT(arg, value); + reflection->SetFloat(message, field_descriptor, value); + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE: { + GOOGLE_CHECK_GET_DOUBLE(arg, value); + reflection->SetDouble(message, field_descriptor, value); + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_BOOL: { + GOOGLE_CHECK_GET_BOOL(arg, value); + reflection->SetBool(message, field_descriptor, value); + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_STRING: { + if (!CheckAndSetString( + arg, message, field_descriptor, reflection, false, -1)) { + return NULL; + } + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_ENUM: { + GOOGLE_CHECK_GET_INT32(arg, value); + const google::protobuf::EnumDescriptor* enum_descriptor = + field_descriptor->enum_type(); + const google::protobuf::EnumValueDescriptor* enum_value = + enum_descriptor->FindValueByNumber(value); + if (enum_value != NULL) { + reflection->SetEnum(message, field_descriptor, enum_value); + } else { + bool added = false; + // Add the value to the unknown fields. + google::protobuf::UnknownFieldSet* unknown_field_set = + message->GetReflection()->MutableUnknownFields(message); + for (int i = 0; i < unknown_field_set->field_count(); ++i) { + if (unknown_field_set->field(i).number() == + field_descriptor->number()) { + unknown_field_set->mutable_field(i)->set_varint(value); + added = true; + break; + } + } + + if (!added) { + unknown_field_set->AddVarint(field_descriptor->number(), value); + } + reflection->ClearField(message, field_descriptor); + } + break; + } + default: + PyErr_Format( + PyExc_SystemError, "Setting value to a field of unknown type %d", + field_descriptor->cpp_type()); + } + + Py_RETURN_NONE; +} + +static PyObject* InternalAddRepeatedScalar( + google::protobuf::Message* message, const google::protobuf::FieldDescriptor* field_descriptor, + PyObject* arg) { + + if (!FIELD_BELONGS_TO_MESSAGE(field_descriptor, message)) { + PyErr_SetString( + PyExc_KeyError, "Field does not belong to message!"); + return NULL; + } + + const google::protobuf::Reflection* reflection = message->GetReflection(); + switch (field_descriptor->cpp_type()) { + case google::protobuf::FieldDescriptor::CPPTYPE_INT32: { + GOOGLE_CHECK_GET_INT32(arg, value); + reflection->AddInt32(message, field_descriptor, value); + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_INT64: { + GOOGLE_CHECK_GET_INT64(arg, value); + reflection->AddInt64(message, field_descriptor, value); + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_UINT32: { + GOOGLE_CHECK_GET_UINT32(arg, value); + reflection->AddUInt32(message, field_descriptor, value); + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_UINT64: { + GOOGLE_CHECK_GET_UINT64(arg, value); + reflection->AddUInt64(message, field_descriptor, value); + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT: { + GOOGLE_CHECK_GET_FLOAT(arg, value); + reflection->AddFloat(message, field_descriptor, value); + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE: { + GOOGLE_CHECK_GET_DOUBLE(arg, value); + reflection->AddDouble(message, field_descriptor, value); + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_BOOL: { + GOOGLE_CHECK_GET_BOOL(arg, value); + reflection->AddBool(message, field_descriptor, value); + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_STRING: { + if (!CheckAndSetString( + arg, message, field_descriptor, reflection, true, -1)) { + return NULL; + } + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_ENUM: { + GOOGLE_CHECK_GET_INT32(arg, value); + const google::protobuf::EnumDescriptor* enum_descriptor = + field_descriptor->enum_type(); + const google::protobuf::EnumValueDescriptor* enum_value = + enum_descriptor->FindValueByNumber(value); + if (enum_value != NULL) { + reflection->AddEnum(message, field_descriptor, enum_value); + } else { + PyObject* s = PyObject_Str(arg); + PyErr_Format(PyExc_ValueError, "Unknown enum value: %s", + PyString_AS_STRING(s)); + Py_DECREF(s); + return NULL; + } + break; + } + default: + PyErr_Format( + PyExc_SystemError, "Adding value to a field of unknown type %d", + field_descriptor->cpp_type()); + } + + Py_RETURN_NONE; +} + +static PyObject* InternalGetRepeatedScalar( + CMessage* cmessage, const google::protobuf::FieldDescriptor* field_descriptor, + int index) { + google::protobuf::Message* message = cmessage->message; + const google::protobuf::Reflection* reflection = message->GetReflection(); + + int field_size = reflection->FieldSize(*message, field_descriptor); + if (index < 0) { + index = field_size + index; + } + if (index < 0 || index >= field_size) { + PyErr_Format(PyExc_IndexError, + "list assignment index (%d) out of range", index); + return NULL; + } + + PyObject* result = NULL; + switch (field_descriptor->cpp_type()) { + case google::protobuf::FieldDescriptor::CPPTYPE_INT32: { + int32 value = reflection->GetRepeatedInt32( + *message, field_descriptor, index); + result = PyInt_FromLong(value); + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_INT64: { + int64 value = reflection->GetRepeatedInt64( + *message, field_descriptor, index); + result = PyLong_FromLongLong(value); + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_UINT32: { + uint32 value = reflection->GetRepeatedUInt32( + *message, field_descriptor, index); + result = PyLong_FromLongLong(value); + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_UINT64: { + uint64 value = reflection->GetRepeatedUInt64( + *message, field_descriptor, index); + result = PyLong_FromUnsignedLongLong(value); + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT: { + float value = reflection->GetRepeatedFloat( + *message, field_descriptor, index); + result = PyFloat_FromDouble(value); + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE: { + double value = reflection->GetRepeatedDouble( + *message, field_descriptor, index); + result = PyFloat_FromDouble(value); + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_BOOL: { + bool value = reflection->GetRepeatedBool( + *message, field_descriptor, index); + result = PyBool_FromLong(value ? 1 : 0); + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_ENUM: { + const google::protobuf::EnumValueDescriptor* enum_value = + message->GetReflection()->GetRepeatedEnum( + *message, field_descriptor, index); + result = PyInt_FromLong(enum_value->number()); + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_STRING: { + string value = reflection->GetRepeatedString( + *message, field_descriptor, index); + result = ToStringObject(field_descriptor, value); + break; + } + case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE: { + CMessage* py_cmsg = PyObject_New(CMessage, &CMessage_Type); + if (py_cmsg == NULL) { + return NULL; + } + const google::protobuf::Message& msg = reflection->GetRepeatedMessage( + *message, field_descriptor, index); + py_cmsg->parent = cmessage; + py_cmsg->full_name = field_descriptor->full_name().c_str(); + py_cmsg->message = const_cast<google::protobuf::Message*>(&msg); + py_cmsg->free_message = false; + py_cmsg->read_only = false; + result = reinterpret_cast<PyObject*>(py_cmsg); + break; + } + default: + PyErr_Format( + PyExc_SystemError, + "Getting value from a repeated field of unknown type %d", + field_descriptor->cpp_type()); + } + + return result; +} + +static PyObject* InternalGetRepeatedScalarSlice( + CMessage* cmessage, const google::protobuf::FieldDescriptor* field_descriptor, + PyObject* slice) { + Py_ssize_t from; + Py_ssize_t to; + Py_ssize_t step; + Py_ssize_t length; + bool return_list = false; + google::protobuf::Message* message = cmessage->message; + + if (PyInt_Check(slice)) { + from = to = PyInt_AsLong(slice); + } else if (PyLong_Check(slice)) { + from = to = PyLong_AsLong(slice); + } else if (PySlice_Check(slice)) { + const google::protobuf::Reflection* reflection = message->GetReflection(); + length = reflection->FieldSize(*message, field_descriptor); + PySlice_GetIndices( + reinterpret_cast<PySliceObject*>(slice), length, &from, &to, &step); + return_list = true; + } else { + PyErr_SetString(PyExc_TypeError, "list indices must be integers"); + return NULL; + } + + if (!return_list) { + return InternalGetRepeatedScalar(cmessage, field_descriptor, from); + } + + PyObject* list = PyList_New(0); + if (list == NULL) { + return NULL; + } + + if (from <= to) { + if (step < 0) return list; + for (Py_ssize_t index = from; index < to; index += step) { + if (index < 0 || index >= length) break; + PyObject* s = InternalGetRepeatedScalar( + cmessage, field_descriptor, index); + PyList_Append(list, s); + Py_DECREF(s); + } + } else { + if (step > 0) return list; + for (Py_ssize_t index = from; index > to; index += step) { + if (index < 0 || index >= length) break; + PyObject* s = InternalGetRepeatedScalar( + cmessage, field_descriptor, index); + PyList_Append(list, s); + Py_DECREF(s); + } + } + return list; +} + +// ------ C Constructor/Destructor: + +static int CMessageInit(CMessage* self, PyObject *args, PyObject *kwds) { + self->message = NULL; + return 0; +} + +static void CMessageDealloc(CMessage* self) { + if (self->free_message) { + if (self->read_only) { + PyErr_WriteUnraisable(reinterpret_cast<PyObject*>(self)); + } + delete self->message; + } + self->ob_type->tp_free(reinterpret_cast<PyObject*>(self)); +} + +// ------ Methods: + +static PyObject* CMessage_Clear(CMessage* self, PyObject* args) { + AssureWritable(self); + self->message->Clear(); + Py_RETURN_NONE; +} + +static PyObject* CMessage_IsInitialized(CMessage* self, PyObject* args) { + return PyBool_FromLong(self->message->IsInitialized() ? 1 : 0); +} + +static PyObject* CMessage_HasField(CMessage* self, PyObject* arg) { + char* field_name; + if (PyString_AsStringAndSize(arg, &field_name, NULL) < 0) { + return NULL; + } + + google::protobuf::Message* message = self->message; + const google::protobuf::Descriptor* descriptor = message->GetDescriptor(); + const google::protobuf::FieldDescriptor* field_descriptor = + descriptor->FindFieldByName(field_name); + if (field_descriptor == NULL) { + PyErr_Format(PyExc_ValueError, "Unknown field %s.", field_name); + return NULL; + } + + bool has_field = + message->GetReflection()->HasField(*message, field_descriptor); + return PyBool_FromLong(has_field ? 1 : 0); +} + +static PyObject* CMessage_HasFieldByDescriptor(CMessage* self, PyObject* arg) { + CFieldDescriptor* cfield_descriptor = NULL; + if (!PyObject_TypeCheck(reinterpret_cast<PyObject *>(arg), + &CFieldDescriptor_Type)) { + PyErr_SetString(PyExc_TypeError, "Must be a field descriptor"); + return NULL; + } + cfield_descriptor = reinterpret_cast<CFieldDescriptor*>(arg); + + google::protobuf::Message* message = self->message; + const google::protobuf::FieldDescriptor* field_descriptor = + cfield_descriptor->descriptor; + + if (!FIELD_BELONGS_TO_MESSAGE(field_descriptor, message)) { + PyErr_SetString(PyExc_KeyError, + "Field does not belong to message!"); + return NULL; + } + + if (FIELD_IS_REPEATED(field_descriptor)) { + PyErr_SetString(PyExc_KeyError, + "Field is repeated. A singular method is required."); + return NULL; + } + + bool has_field = + message->GetReflection()->HasField(*message, field_descriptor); + return PyBool_FromLong(has_field ? 1 : 0); +} + +static PyObject* CMessage_ClearFieldByDescriptor( + CMessage* self, PyObject* arg) { + CFieldDescriptor* cfield_descriptor = NULL; + if (!PyObject_TypeCheck(reinterpret_cast<PyObject *>(arg), + &CFieldDescriptor_Type)) { + PyErr_SetString(PyExc_TypeError, "Must be a field descriptor"); + return NULL; + } + cfield_descriptor = reinterpret_cast<CFieldDescriptor*>(arg); + + google::protobuf::Message* message = self->message; + const google::protobuf::FieldDescriptor* field_descriptor = + cfield_descriptor->descriptor; + + if (!FIELD_BELONGS_TO_MESSAGE(field_descriptor, message)) { + PyErr_SetString(PyExc_KeyError, + "Field does not belong to message!"); + return NULL; + } + + message->GetReflection()->ClearField(message, field_descriptor); + Py_RETURN_NONE; +} + +static PyObject* CMessage_ClearField(CMessage* self, PyObject* arg) { + char* field_name; + if (PyString_AsStringAndSize(arg, &field_name, NULL) < 0) { + return NULL; + } + + google::protobuf::Message* message = self->message; + const google::protobuf::Descriptor* descriptor = message->GetDescriptor(); + const google::protobuf::FieldDescriptor* field_descriptor = + descriptor->FindFieldByName(field_name); + if (field_descriptor == NULL) { + PyErr_Format(PyExc_ValueError, "Unknown field %s.", field_name); + return NULL; + } + + message->GetReflection()->ClearField(message, field_descriptor); + Py_RETURN_NONE; +} + +static PyObject* CMessage_GetScalar(CMessage* self, PyObject* arg) { + CFieldDescriptor* cdescriptor = NULL; + if (!PyObject_TypeCheck(reinterpret_cast<PyObject *>(arg), + &CFieldDescriptor_Type)) { + PyErr_SetString(PyExc_TypeError, "Must be a field descriptor"); + return NULL; + } + cdescriptor = reinterpret_cast<CFieldDescriptor*>(arg); + + google::protobuf::Message* message = self->message; + return InternalGetScalar(message, cdescriptor->descriptor); +} + +static PyObject* CMessage_GetRepeatedScalar(CMessage* self, PyObject* args) { + CFieldDescriptor* cfield_descriptor; + PyObject* slice; + if (!PyArg_ParseTuple(args, C("O!O:GetRepeatedScalar"), + &CFieldDescriptor_Type, &cfield_descriptor, &slice)) { + return NULL; + } + + return InternalGetRepeatedScalarSlice( + self, cfield_descriptor->descriptor, slice); +} + +static PyObject* CMessage_AssignRepeatedScalar(CMessage* self, PyObject* args) { + CFieldDescriptor* cfield_descriptor; + PyObject* slice; + if (!PyArg_ParseTuple(args, C("O!O:AssignRepeatedScalar"), + &CFieldDescriptor_Type, &cfield_descriptor, &slice)) { + return NULL; + } + + AssureWritable(self); + google::protobuf::Message* message = self->message; + message->GetReflection()->ClearField(message, cfield_descriptor->descriptor); + + PyObject* iter = PyObject_GetIter(slice); + PyObject* next; + while ((next = PyIter_Next(iter)) != NULL) { + if (InternalAddRepeatedScalar( + message, cfield_descriptor->descriptor, next) == NULL) { + Py_DECREF(iter); + return NULL; + } + } + Py_DECREF(iter); + Py_RETURN_NONE; +} + +static PyObject* CMessage_DeleteRepeatedField(CMessage* self, PyObject* args) { + CFieldDescriptor* cfield_descriptor; + PyObject* slice; + if (!PyArg_ParseTuple(args, C("O!O:DeleteRepeatedField"), + &CFieldDescriptor_Type, &cfield_descriptor, &slice)) { + return NULL; + } + AssureWritable(self); + + Py_ssize_t length, from, to, step, slice_length; + google::protobuf::Message* message = self->message; + const google::protobuf::FieldDescriptor* field_descriptor = + cfield_descriptor->descriptor; + const google::protobuf::Reflection* reflection = message->GetReflection(); + int min, max; + length = reflection->FieldSize(*message, field_descriptor); + + if (PyInt_Check(slice) || PyLong_Check(slice)) { + from = to = PyLong_AsLong(slice); + if (from < 0) { + from = to = length + from; + } + step = 1; + min = max = from; + + // Range check. + if (from < 0 || from >= length) { + PyErr_Format(PyExc_IndexError, "list assignment index out of range"); + return NULL; + } + } else if (PySlice_Check(slice)) { + from = to = step = slice_length = 0; + PySlice_GetIndicesEx( + reinterpret_cast<PySliceObject*>(slice), + length, &from, &to, &step, &slice_length); + if (from < to) { + min = from; + max = to - 1; + } else { + min = to + 1; + max = from; + } + } else { + PyErr_SetString(PyExc_TypeError, "list indices must be integers"); + return NULL; + } + + Py_ssize_t i = from; + std::vector<bool> to_delete(length, false); + while (i >= min && i <= max) { + to_delete[i] = true; + i += step; + } + + to = 0; + for (i = 0; i < length; ++i) { + if (!to_delete[i]) { + if (i != to) { + reflection->SwapElements(message, field_descriptor, i, to); + } + ++to; + } + } + + while (i > to) { + reflection->RemoveLast(message, field_descriptor); + --i; + } + + Py_RETURN_NONE; +} + + +static PyObject* CMessage_SetScalar(CMessage* self, PyObject* args) { + CFieldDescriptor* cfield_descriptor; + PyObject* arg; + if (!PyArg_ParseTuple(args, C("O!O:SetScalar"), + &CFieldDescriptor_Type, &cfield_descriptor, &arg)) { + return NULL; + } + AssureWritable(self); + + return InternalSetScalar(self->message, cfield_descriptor->descriptor, arg); +} + +static PyObject* CMessage_AddRepeatedScalar(CMessage* self, PyObject* args) { + CFieldDescriptor* cfield_descriptor; + PyObject* value; + if (!PyArg_ParseTuple(args, C("O!O:AddRepeatedScalar"), + &CFieldDescriptor_Type, &cfield_descriptor, &value)) { + return NULL; + } + AssureWritable(self); + + return InternalAddRepeatedScalar( + self->message, cfield_descriptor->descriptor, value); +} + +static PyObject* CMessage_FieldLength(CMessage* self, PyObject* arg) { + CFieldDescriptor* cfield_descriptor; + if (!PyObject_TypeCheck(reinterpret_cast<PyObject *>(arg), + &CFieldDescriptor_Type)) { + PyErr_SetString(PyExc_TypeError, "Must be a field descriptor"); + return NULL; + } + cfield_descriptor = reinterpret_cast<CFieldDescriptor*>(arg); + + google::protobuf::Message* message = self->message; + int length = message->GetReflection()->FieldSize( + *message, cfield_descriptor->descriptor); + return PyInt_FromLong(length); +} + +static PyObject* CMessage_DebugString(CMessage* self, PyObject* args) { + return PyString_FromString(self->message->DebugString().c_str()); +} + +static PyObject* CMessage_SerializeToString(CMessage* self, PyObject* args) { + int size = self->message->ByteSize(); + if (size <= 0) { + return PyString_FromString(""); + } + PyObject* result = PyString_FromStringAndSize(NULL, size); + if (result == NULL) { + return NULL; + } + char* buffer = PyString_AS_STRING(result); + self->message->SerializeWithCachedSizesToArray( + reinterpret_cast<uint8*>(buffer)); + return result; +} + +static PyObject* CMessage_SerializePartialToString( + CMessage* self, PyObject* args) { + string contents; + self->message->SerializePartialToString(&contents); + return PyString_FromStringAndSize(contents.c_str(), contents.size()); +} + +static PyObject* CMessageStr(CMessage* self) { + char str[1024]; + str[sizeof(str) - 1] = 0; + snprintf(str, sizeof(str) - 1, "CMessage: <%p>", self->message); + return PyString_FromString(str); +} + +static PyObject* CMessage_MergeFrom(CMessage* self, PyObject* arg) { + CMessage* other_message; + if (!PyObject_TypeCheck(reinterpret_cast<PyObject *>(arg), &CMessage_Type)) { + PyErr_SetString(PyExc_TypeError, "Must be a message"); + return NULL; + } + + other_message = reinterpret_cast<CMessage*>(arg); + if (other_message->message->GetDescriptor() != + self->message->GetDescriptor()) { + PyErr_Format(PyExc_TypeError, + "Tried to merge from a message with a different type. " + "to: %s, from: %s", + self->message->GetDescriptor()->full_name().c_str(), + other_message->message->GetDescriptor()->full_name().c_str()); + return NULL; + } + AssureWritable(self); + + self->message->MergeFrom(*other_message->message); + Py_RETURN_NONE; +} + +static PyObject* CMessage_CopyFrom(CMessage* self, PyObject* arg) { + CMessage* other_message; + if (!PyObject_TypeCheck(reinterpret_cast<PyObject *>(arg), &CMessage_Type)) { + PyErr_SetString(PyExc_TypeError, "Must be a message"); + return NULL; + } + + other_message = reinterpret_cast<CMessage*>(arg); + if (other_message->message->GetDescriptor() != + self->message->GetDescriptor()) { + PyErr_Format(PyExc_TypeError, + "Tried to copy from a message with a different type. " + "to: %s, from: %s", + self->message->GetDescriptor()->full_name().c_str(), + other_message->message->GetDescriptor()->full_name().c_str()); + return NULL; + } + + AssureWritable(self); + + self->message->CopyFrom(*other_message->message); + Py_RETURN_NONE; +} + +static PyObject* CMessage_MergeFromString(CMessage* self, PyObject* arg) { + const void* data; + Py_ssize_t data_length; + if (PyObject_AsReadBuffer(arg, &data, &data_length) < 0) { + return NULL; + } + + AssureWritable(self); + google::protobuf::io::CodedInputStream input( + reinterpret_cast<const uint8*>(data), data_length); + bool success = self->message->MergePartialFromCodedStream(&input); + if (success) { + return PyInt_FromLong(self->message->ByteSize()); + } else { + return PyInt_FromLong(-1); + } +} + +static PyObject* CMessage_ByteSize(CMessage* self, PyObject* args) { + return PyLong_FromLong(self->message->ByteSize()); +} + +static PyObject* CMessage_SetInParent(CMessage* self, PyObject* args) { + AssureWritable(self); + Py_RETURN_NONE; +} + +static PyObject* CMessage_SwapRepeatedFieldElements( + CMessage* self, PyObject* args) { + CFieldDescriptor* cfield_descriptor; + int index1, index2; + if (!PyArg_ParseTuple(args, C("O!ii:SwapRepeatedFieldElements"), + &CFieldDescriptor_Type, &cfield_descriptor, + &index1, &index2)) { + return NULL; + } + + google::protobuf::Message* message = self->message; + const google::protobuf::Reflection* reflection = message->GetReflection(); + + reflection->SwapElements( + message, cfield_descriptor->descriptor, index1, index2); + Py_RETURN_NONE; +} + +static PyObject* CMessage_AddMessage(CMessage* self, PyObject* arg) { + CFieldDescriptor* cfield_descriptor; + if (!PyObject_TypeCheck(reinterpret_cast<PyObject *>(arg), + &CFieldDescriptor_Type)) { + PyErr_SetString(PyExc_TypeError, "Must be a field descriptor"); + return NULL; + } + cfield_descriptor = reinterpret_cast<CFieldDescriptor*>(arg); + AssureWritable(self); + + CMessage* py_cmsg = PyObject_New(CMessage, &CMessage_Type); + if (py_cmsg == NULL) { + return NULL; + } + + google::protobuf::Message* message = self->message; + const google::protobuf::Reflection* reflection = message->GetReflection(); + google::protobuf::Message* sub_message = + reflection->AddMessage(message, cfield_descriptor->descriptor); + + py_cmsg->parent = NULL; + py_cmsg->full_name = sub_message->GetDescriptor()->full_name().c_str(); + py_cmsg->message = sub_message; + py_cmsg->free_message = false; + py_cmsg->read_only = false; + return reinterpret_cast<PyObject*>(py_cmsg); +} + +static PyObject* CMessage_GetRepeatedMessage(CMessage* self, PyObject* args) { + CFieldDescriptor* cfield_descriptor; + PyObject* slice; + if (!PyArg_ParseTuple(args, C("O!O:GetRepeatedMessage"), + &CFieldDescriptor_Type, &cfield_descriptor, &slice)) { + return NULL; + } + + return InternalGetRepeatedScalarSlice( + self, cfield_descriptor->descriptor, slice); +} + +static PyObject* CMessage_NewSubMessage(CMessage* self, PyObject* arg) { + CFieldDescriptor* cfield_descriptor; + if (!PyObject_TypeCheck(reinterpret_cast<PyObject *>(arg), + &CFieldDescriptor_Type)) { + PyErr_SetString(PyExc_TypeError, "Must be a field descriptor"); + return NULL; + } + cfield_descriptor = reinterpret_cast<CFieldDescriptor*>(arg); + + CMessage* py_cmsg = PyObject_New(CMessage, &CMessage_Type); + if (py_cmsg == NULL) { + return NULL; + } + + google::protobuf::Message* message = self->message; + const google::protobuf::Reflection* reflection = message->GetReflection(); + const google::protobuf::Message& sub_message = + reflection->GetMessage(*message, cfield_descriptor->descriptor, + global_message_factory); + + py_cmsg->full_name = sub_message.GetDescriptor()->full_name().c_str(); + py_cmsg->parent = self; + py_cmsg->parent_field = cfield_descriptor; + py_cmsg->message = const_cast<google::protobuf::Message*>(&sub_message); + py_cmsg->free_message = false; + py_cmsg->read_only = true; + return reinterpret_cast<PyObject*>(py_cmsg); +} + +static PyObject* CMessage_MutableMessage(CMessage* self, PyObject* arg) { + CFieldDescriptor* cfield_descriptor; + if (!PyObject_TypeCheck(reinterpret_cast<PyObject *>(arg), + &CFieldDescriptor_Type)) { + PyErr_SetString(PyExc_TypeError, "Must be a field descriptor"); + return NULL; + } + cfield_descriptor = reinterpret_cast<CFieldDescriptor*>(arg); + AssureWritable(self); + + CMessage* py_cmsg = PyObject_New(CMessage, &CMessage_Type); + if (py_cmsg == NULL) { + return NULL; + } + + google::protobuf::Message* message = self->message; + const google::protobuf::Reflection* reflection = message->GetReflection(); + google::protobuf::Message* mutable_message = + reflection->MutableMessage(message, cfield_descriptor->descriptor, + global_message_factory); + + py_cmsg->full_name = mutable_message->GetDescriptor()->full_name().c_str(); + py_cmsg->message = mutable_message; + py_cmsg->free_message = false; + py_cmsg->read_only = false; + return reinterpret_cast<PyObject*>(py_cmsg); +} + +static PyObject* CMessage_Equals(CMessage* self, PyObject* arg) { + CMessage* other_message; + if (!PyObject_TypeCheck(reinterpret_cast<PyObject *>(arg), &CMessage_Type)) { + PyErr_SetString(PyExc_TypeError, "Must be a message"); + return NULL; + } + other_message = reinterpret_cast<CMessage*>(arg); + + if (other_message->message == self->message) { + return PyBool_FromLong(1); + } + + if (other_message->message->GetDescriptor() != + self->message->GetDescriptor()) { + return PyBool_FromLong(0); + } + + return PyBool_FromLong(1); +} + +static PyObject* CMessage_ListFields(CMessage* self, PyObject* args) { + google::protobuf::Message* message = self->message; + const google::protobuf::Reflection* reflection = message->GetReflection(); + vector<const google::protobuf::FieldDescriptor*> fields; + reflection->ListFields(*message, &fields); + + PyObject* list = PyList_New(fields.size()); + if (list == NULL) { + return NULL; + } + + for (unsigned int i = 0; i < fields.size(); ++i) { + bool is_extension = fields[i]->is_extension(); + PyObject* t = PyTuple_New(2); + if (t == NULL) { + Py_DECREF(list); + return NULL; + } + + PyObject* is_extension_object = PyBool_FromLong(is_extension ? 1 : 0); + + PyObject* field_name; + const string* s; + if (is_extension) { + s = &fields[i]->full_name(); + } else { + s = &fields[i]->name(); + } + field_name = PyString_FromStringAndSize(s->c_str(), s->length()); + if (field_name == NULL) { + Py_DECREF(list); + Py_DECREF(t); + return NULL; + } + + PyTuple_SET_ITEM(t, 0, is_extension_object); + PyTuple_SET_ITEM(t, 1, field_name); + PyList_SET_ITEM(list, i, t); + } + + return list; +} + +static PyObject* CMessage_FindInitializationErrors(CMessage* self) { + google::protobuf::Message* message = self->message; + vector<string> errors; + message->FindInitializationErrors(&errors); + + PyObject* error_list = PyList_New(errors.size()); + if (error_list == NULL) { + return NULL; + } + for (unsigned int i = 0; i < errors.size(); ++i) { + const string& error = errors[i]; + PyObject* error_string = PyString_FromStringAndSize( + error.c_str(), error.length()); + if (error_string == NULL) { + Py_DECREF(error_list); + return NULL; + } + PyList_SET_ITEM(error_list, i, error_string); + } + return error_list; +} + +// ------ Python Constructor: + +PyObject* Python_NewCMessage(PyObject* ignored, PyObject* arg) { + const char* message_type = PyString_AsString(arg); + if (message_type == NULL) { + return NULL; + } + + const google::protobuf::Message* message = CreateMessage(message_type); + if (message == NULL) { + PyErr_Format(PyExc_TypeError, "Couldn't create message of type %s!", + message_type); + return NULL; + } + + CMessage* py_cmsg = PyObject_New(CMessage, &CMessage_Type); + if (py_cmsg == NULL) { + return NULL; + } + py_cmsg->message = message->New(); + py_cmsg->free_message = true; + py_cmsg->full_name = message->GetDescriptor()->full_name().c_str(); + py_cmsg->read_only = false; + py_cmsg->parent = NULL; + py_cmsg->parent_field = NULL; + return reinterpret_cast<PyObject*>(py_cmsg); +} + +// --- Module Functions (exposed to Python): + +PyMethodDef methods[] = { + { C("NewCMessage"), (PyCFunction)Python_NewCMessage, + METH_O, + C("Creates a new C++ protocol message, given its full name.") }, + { C("NewCDescriptorPool"), (PyCFunction)Python_NewCDescriptorPool, + METH_NOARGS, + C("Creates a new C++ descriptor pool.") }, + { C("BuildFile"), (PyCFunction)Python_BuildFile, + METH_O, + C("Registers a new protocol buffer file in the global C++ descriptor " + "pool.") }, + {NULL} +}; + +// --- Exposing the C proto living inside Python proto to C code: + +extern const Message* (*GetCProtoInsidePyProtoPtr)(PyObject* msg); +extern Message* (*MutableCProtoInsidePyProtoPtr)(PyObject* msg); + +static const google::protobuf::Message* GetCProtoInsidePyProtoImpl(PyObject* msg) { + PyObject* c_msg_obj = PyObject_GetAttrString(msg, "_cmsg"); + if (c_msg_obj == NULL) { + PyErr_Clear(); + return NULL; + } + Py_DECREF(c_msg_obj); + if (!PyObject_TypeCheck(c_msg_obj, &CMessage_Type)) { + return NULL; + } + CMessage* c_msg = reinterpret_cast<CMessage*>(c_msg_obj); + return c_msg->message; +} + +static google::protobuf::Message* MutableCProtoInsidePyProtoImpl(PyObject* msg) { + PyObject* c_msg_obj = PyObject_GetAttrString(msg, "_cmsg"); + if (c_msg_obj == NULL) { + PyErr_Clear(); + return NULL; + } + Py_DECREF(c_msg_obj); + if (!PyObject_TypeCheck(c_msg_obj, &CMessage_Type)) { + return NULL; + } + CMessage* c_msg = reinterpret_cast<CMessage*>(c_msg_obj); + AssureWritable(c_msg); + return c_msg->message; +} + +// --- Module Init Function: + +static const char module_docstring[] = +"python-proto2 is a module that can be used to enhance proto2 Python API\n" +"performance.\n" +"\n" +"It provides access to the protocol buffers C++ reflection API that\n" +"implements the basic protocol buffer functions."; + +extern "C" { + void init_net_proto2___python() { + // Initialize constants. + kPythonZero = PyInt_FromLong(0); + kint32min_py = PyInt_FromLong(kint32min); + kint32max_py = PyInt_FromLong(kint32max); + kuint32max_py = PyLong_FromLongLong(kuint32max); + kint64min_py = PyLong_FromLongLong(kint64min); + kint64max_py = PyLong_FromLongLong(kint64max); + kuint64max_py = PyLong_FromUnsignedLongLong(kuint64max); + + global_message_factory = new DynamicMessageFactory(GetDescriptorPool()); + global_message_factory->SetDelegateToGeneratedFactory(true); + + // Export our functions to Python. + PyObject *m; + m = Py_InitModule3(C("_net_proto2___python"), methods, C(module_docstring)); + if (m == NULL) { + return; + } + + AddConstants(m); + + CMessage_Type.tp_new = PyType_GenericNew; + if (PyType_Ready(&CMessage_Type) < 0) { + return; + } + + if (!InitDescriptor()) { + return; + } + + // Override {Get,Mutable}CProtoInsidePyProto. + GetCProtoInsidePyProtoPtr = GetCProtoInsidePyProtoImpl; + MutableCProtoInsidePyProtoPtr = MutableCProtoInsidePyProtoImpl; + } +} + +} // namespace python +} // namespace protobuf +} // namespace google diff --git a/third_party/protobuf/python/google/protobuf/pyext/python_descriptor.cc b/third_party/protobuf/python/google/protobuf/pyext/python_descriptor.cc new file mode 100644 index 0000000..fb87bad --- /dev/null +++ b/third_party/protobuf/python/google/protobuf/pyext/python_descriptor.cc @@ -0,0 +1,334 @@ +// 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: petar@google.com (Petar Petrov) + +#include <Python.h> + +#include <google/protobuf/pyext/python_descriptor.h> +#include <google/protobuf/descriptor.pb.h> + +#define C(str) const_cast<char*>(str) + +namespace google { +namespace protobuf { +namespace python { + +static void CFieldDescriptorDealloc(CFieldDescriptor* self); + +static google::protobuf::DescriptorPool* g_descriptor_pool = NULL; + +static PyObject* CFieldDescriptor_GetFullName( + CFieldDescriptor* self, void *closure) { + Py_XINCREF(self->full_name); + return self->full_name; +} + +static PyObject* CFieldDescriptor_GetName( + CFieldDescriptor *self, void *closure) { + Py_XINCREF(self->name); + return self->name; +} + +static PyObject* CFieldDescriptor_GetCppType( + CFieldDescriptor *self, void *closure) { + Py_XINCREF(self->cpp_type); + return self->cpp_type; +} + +static PyObject* CFieldDescriptor_GetLabel( + CFieldDescriptor *self, void *closure) { + Py_XINCREF(self->label); + return self->label; +} + +static PyObject* CFieldDescriptor_GetID( + CFieldDescriptor *self, void *closure) { + Py_XINCREF(self->id); + return self->id; +} + + +static PyGetSetDef CFieldDescriptorGetters[] = { + { C("full_name"), + (getter)CFieldDescriptor_GetFullName, NULL, "Full name", NULL}, + { C("name"), + (getter)CFieldDescriptor_GetName, NULL, "last name", NULL}, + { C("cpp_type"), + (getter)CFieldDescriptor_GetCppType, NULL, "C++ Type", NULL}, + { C("label"), + (getter)CFieldDescriptor_GetLabel, NULL, "Label", NULL}, + { C("id"), + (getter)CFieldDescriptor_GetID, NULL, "ID", NULL}, + {NULL} +}; + +PyTypeObject CFieldDescriptor_Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, + C("google3.net.google.protobuf.python.internal." + "_net_proto2___python." + "CFieldDescriptor"), // tp_name + sizeof(CFieldDescriptor), // tp_basicsize + 0, // tp_itemsize + (destructor)CFieldDescriptorDealloc, // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + 0, // tp_repr + 0, // tp_as_number + 0, // tp_as_sequence + 0, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + 0, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + C("A Field Descriptor"), // tp_doc + 0, // tp_traverse + 0, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + 0, // tp_methods + 0, // tp_members + CFieldDescriptorGetters, // tp_getset + 0, // tp_base + 0, // tp_dict + 0, // tp_descr_get + 0, // tp_descr_set + 0, // tp_dictoffset + 0, // tp_init + PyType_GenericAlloc, // tp_alloc + PyType_GenericNew, // tp_new + PyObject_Del, // tp_free +}; + +static void CFieldDescriptorDealloc(CFieldDescriptor* self) { + Py_DECREF(self->full_name); + Py_DECREF(self->name); + Py_DECREF(self->cpp_type); + Py_DECREF(self->label); + Py_DECREF(self->id); + self->ob_type->tp_free(reinterpret_cast<PyObject*>(self)); +} + +typedef struct { + PyObject_HEAD + + const google::protobuf::DescriptorPool* pool; +} CDescriptorPool; + +static void CDescriptorPoolDealloc(CDescriptorPool* self); + +static PyObject* CDescriptorPool_NewCDescriptor( + const google::protobuf::FieldDescriptor* field_descriptor) { + CFieldDescriptor* cfield_descriptor = PyObject_New( + CFieldDescriptor, &CFieldDescriptor_Type); + if (cfield_descriptor == NULL) { + return NULL; + } + cfield_descriptor->descriptor = field_descriptor; + + cfield_descriptor->full_name = PyString_FromString( + field_descriptor->full_name().c_str()); + cfield_descriptor->name = PyString_FromString( + field_descriptor->name().c_str()); + cfield_descriptor->cpp_type = PyLong_FromLong(field_descriptor->cpp_type()); + cfield_descriptor->label = PyLong_FromLong(field_descriptor->label()); + cfield_descriptor->id = PyLong_FromVoidPtr(cfield_descriptor); + return reinterpret_cast<PyObject*>(cfield_descriptor); +} + +static PyObject* CDescriptorPool_FindFieldByName( + CDescriptorPool* self, PyObject* arg) { + const char* full_field_name = PyString_AsString(arg); + if (full_field_name == NULL) { + return NULL; + } + + const google::protobuf::FieldDescriptor* field_descriptor = NULL; + + field_descriptor = self->pool->FindFieldByName(full_field_name); + if (field_descriptor == NULL) { + PyErr_Format(PyExc_TypeError, "Couldn't find field %.200s", + full_field_name); + return NULL; + } + + return CDescriptorPool_NewCDescriptor(field_descriptor); +} + +static PyObject* CDescriptorPool_FindExtensionByName( + CDescriptorPool* self, PyObject* arg) { + const char* full_field_name = PyString_AsString(arg); + if (full_field_name == NULL) { + return NULL; + } + + const google::protobuf::FieldDescriptor* field_descriptor = + self->pool->FindExtensionByName(full_field_name); + if (field_descriptor == NULL) { + PyErr_Format(PyExc_TypeError, "Couldn't find field %.200s", + full_field_name); + return NULL; + } + + return CDescriptorPool_NewCDescriptor(field_descriptor); +} + +static PyMethodDef CDescriptorPoolMethods[] = { + { C("FindFieldByName"), + (PyCFunction)CDescriptorPool_FindFieldByName, + METH_O, + C("Searches for a field descriptor by full name.") }, + { C("FindExtensionByName"), + (PyCFunction)CDescriptorPool_FindExtensionByName, + METH_O, + C("Searches for extension descriptor by full name.") }, + {NULL} +}; + +PyTypeObject CDescriptorPool_Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, + C("google3.net.google.protobuf.python.internal." + "_net_proto2___python." + "CFieldDescriptor"), // tp_name + sizeof(CDescriptorPool), // tp_basicsize + 0, // tp_itemsize + (destructor)CDescriptorPoolDealloc, // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + 0, // tp_repr + 0, // tp_as_number + 0, // tp_as_sequence + 0, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + 0, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + C("A Descriptor Pool"), // tp_doc + 0, // tp_traverse + 0, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + CDescriptorPoolMethods, // tp_methods + 0, // tp_members + 0, // tp_getset + 0, // tp_base + 0, // tp_dict + 0, // tp_descr_get + 0, // tp_descr_set + 0, // tp_dictoffset + 0, // tp_init + PyType_GenericAlloc, // tp_alloc + PyType_GenericNew, // tp_new + PyObject_Del, // tp_free +}; + +static void CDescriptorPoolDealloc(CDescriptorPool* self) { + self->ob_type->tp_free(reinterpret_cast<PyObject*>(self)); +} + +google::protobuf::DescriptorPool* GetDescriptorPool() { + if (g_descriptor_pool == NULL) { + g_descriptor_pool = new google::protobuf::DescriptorPool( + google::protobuf::DescriptorPool::generated_pool()); + } + return g_descriptor_pool; +} + +PyObject* Python_NewCDescriptorPool(PyObject* ignored, PyObject* args) { + CDescriptorPool* cdescriptor_pool = PyObject_New( + CDescriptorPool, &CDescriptorPool_Type); + if (cdescriptor_pool == NULL) { + return NULL; + } + cdescriptor_pool->pool = GetDescriptorPool(); + return reinterpret_cast<PyObject*>(cdescriptor_pool); +} + +PyObject* Python_BuildFile(PyObject* ignored, PyObject* arg) { + char* message_type; + Py_ssize_t message_len; + + if (PyString_AsStringAndSize(arg, &message_type, &message_len) < 0) { + return NULL; + } + + google::protobuf::FileDescriptorProto file_proto; + if (!file_proto.ParseFromArray(message_type, message_len)) { + PyErr_SetString(PyExc_TypeError, "Couldn't parse file content!"); + return NULL; + } + + // If this file is already in the generated pool, don't add it again. + if (google::protobuf::DescriptorPool::generated_pool()->FindFileByName( + file_proto.name()) != NULL) { + Py_RETURN_NONE; + } + + const google::protobuf::FileDescriptor* descriptor = GetDescriptorPool()->BuildFile( + file_proto); + if (descriptor == NULL) { + PyErr_SetString(PyExc_TypeError, + "Couldn't build proto file into descriptor pool!"); + return NULL; + } + + Py_RETURN_NONE; +} + +bool InitDescriptor() { + CFieldDescriptor_Type.tp_new = PyType_GenericNew; + if (PyType_Ready(&CFieldDescriptor_Type) < 0) + return false; + + CDescriptorPool_Type.tp_new = PyType_GenericNew; + if (PyType_Ready(&CDescriptorPool_Type) < 0) + return false; + return true; +} + +} // namespace python +} // namespace protobuf +} // namespace google diff --git a/third_party/protobuf/python/google/protobuf/pyext/python_descriptor.h b/third_party/protobuf/python/google/protobuf/pyext/python_descriptor.h new file mode 100644 index 0000000..5232680 --- /dev/null +++ b/third_party/protobuf/python/google/protobuf/pyext/python_descriptor.h @@ -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: petar@google.com (Petar Petrov) + +#ifndef GOOGLE_PROTOBUF_PYTHON_DESCRIPTOR_H__ +#define GOOGLE_PROTOBUF_PYTHON_DESCRIPTOR_H__ + +#include <Python.h> +#include <structmember.h> + +#include <google/protobuf/descriptor.h> + +#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN) +typedef int Py_ssize_t; +#define PY_SSIZE_T_MAX INT_MAX +#define PY_SSIZE_T_MIN INT_MIN +#endif + +namespace google { +namespace protobuf { +namespace python { + +typedef struct { + PyObject_HEAD + + // The proto2 descriptor that this object represents. + const google::protobuf::FieldDescriptor* descriptor; + + // Full name of the field (PyString). + PyObject* full_name; + + // Name of the field (PyString). + PyObject* name; + + // C++ type of the field (PyLong). + PyObject* cpp_type; + + // Name of the field (PyLong). + PyObject* label; + + // Identity of the descriptor (PyLong used as a poiner). + PyObject* id; +} CFieldDescriptor; + +extern PyTypeObject CFieldDescriptor_Type; + +extern PyTypeObject CDescriptorPool_Type; + + +PyObject* Python_NewCDescriptorPool(PyObject* ignored, PyObject* args); +PyObject* Python_BuildFile(PyObject* ignored, PyObject* args); +bool InitDescriptor(); +google::protobuf::DescriptorPool* GetDescriptorPool(); + +} // namespace python +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_PYTHON_DESCRIPTOR_H__ diff --git a/third_party/protobuf/python/google/protobuf/pyext/python_protobuf.cc b/third_party/protobuf/python/google/protobuf/pyext/python_protobuf.cc new file mode 100644 index 0000000..1b1ab5d --- /dev/null +++ b/third_party/protobuf/python/google/protobuf/pyext/python_protobuf.cc @@ -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: qrczak@google.com (Marcin Kowalczyk) + +#include <google/protobuf/pyext/python_protobuf.h> + +namespace google { +namespace protobuf { +namespace python { + +static const Message* GetCProtoInsidePyProtoStub(PyObject* msg) { + return NULL; +} +static Message* MutableCProtoInsidePyProtoStub(PyObject* msg) { + return NULL; +} + +// This is initialized with a default, stub implementation. +// If python-google.protobuf.cc is loaded, the function pointer is overridden +// with a full implementation. +const Message* (*GetCProtoInsidePyProtoPtr)(PyObject* msg) = + GetCProtoInsidePyProtoStub; +Message* (*MutableCProtoInsidePyProtoPtr)(PyObject* msg) = + MutableCProtoInsidePyProtoStub; + +const Message* GetCProtoInsidePyProto(PyObject* msg) { + return GetCProtoInsidePyProtoPtr(msg); +} +Message* MutableCProtoInsidePyProto(PyObject* msg) { + return MutableCProtoInsidePyProtoPtr(msg); +} + +} // namespace python +} // namespace protobuf +} // namespace google diff --git a/third_party/protobuf/src/google/protobuf/stubs/hash.cc b/third_party/protobuf/python/google/protobuf/pyext/python_protobuf.h index 9eaf4a1..c5b0b1c 100644 --- a/third_party/protobuf/src/google/protobuf/stubs/hash.cc +++ b/third_party/protobuf/python/google/protobuf/pyext/python_protobuf.h @@ -28,14 +28,30 @@ // (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) +// Author: qrczak@google.com (Marcin Kowalczyk) +// +// This module exposes the C proto inside the given Python proto, in +// case the Python proto is implemented with a C proto. + +#ifndef GOOGLE_PROTOBUF_PYTHON_PYTHON_PROTOBUF_H__ +#define GOOGLE_PROTOBUF_PYTHON_PYTHON_PROTOBUF_H__ -#include <google/protobuf/stubs/hash.h> +#include <Python.h> namespace google { namespace protobuf { -// Nothing needed here right now. +class Message; + +namespace python { +// Return the pointer to the C proto inside the given Python proto, +// or NULL when this is not a Python proto implemented with a C proto. +const Message* GetCProtoInsidePyProto(PyObject* msg); +Message* MutableCProtoInsidePyProto(PyObject* msg); + +} // namespace python } // namespace protobuf + } // namespace google +#endif // GOOGLE_PROTOBUF_PYTHON_PYTHON_PROTOBUF_H__ diff --git a/third_party/protobuf/python/google/protobuf/reflection.py b/third_party/protobuf/python/google/protobuf/reflection.py index 45e5ba8..1373c88 100755 --- a/third_party/protobuf/python/google/protobuf/reflection.py +++ b/third_party/protobuf/python/google/protobuf/reflection.py @@ -29,9 +29,6 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # This code is meant to work on Python 2.4 and above only. -# -# TODO(robinson): Helpers for verbose, common checks like seeing if a -# descriptor's cpp_type is CPPTYPE_MESSAGE. """Contains a metaclass and helper functions used to create protocol message classes from Descriptor objects at runtime. @@ -50,27 +47,22 @@ this file*. __author__ = 'robinson@google.com (Will Robinson)' -try: - from cStringIO import StringIO -except ImportError: - from StringIO import StringIO -import struct -import weakref -# We use "as" to avoid name collisions with variables. -from google.protobuf.internal import containers -from google.protobuf.internal import decoder -from google.protobuf.internal import encoder -from google.protobuf.internal import message_listener as message_listener_mod -from google.protobuf.internal import type_checkers -from google.protobuf.internal import wire_format +from google.protobuf.internal import api_implementation from google.protobuf import descriptor as descriptor_mod -from google.protobuf import message as message_mod -from google.protobuf import text_format - _FieldDescriptor = descriptor_mod.FieldDescriptor +if api_implementation.Type() == 'cpp': + from google.protobuf.internal import cpp_message + _NewMessage = cpp_message.NewMessage + _InitMessage = cpp_message.InitMessage +else: + from google.protobuf.internal import python_message + _NewMessage = python_message.NewMessage + _InitMessage = python_message.InitMessage + + class GeneratedProtocolMessageType(type): """Metaclass for protocol message classes created at runtime from Descriptors. @@ -120,10 +112,12 @@ class GeneratedProtocolMessageType(type): Newly-allocated class. """ descriptor = dictionary[GeneratedProtocolMessageType._DESCRIPTOR_KEY] - _AddSlots(descriptor, dictionary) - _AddClassAttributesForNestedExtensions(descriptor, dictionary) + _NewMessage(descriptor, dictionary) superclass = super(GeneratedProtocolMessageType, cls) - return superclass.__new__(cls, name, bases, dictionary) + + new_class = superclass.__new__(cls, name, bases, dictionary) + setattr(descriptor, '_concrete_class', new_class) + return new_class def __init__(cls, name, bases, dictionary): """Here we perform the majority of our work on the class. @@ -143,1018 +137,6 @@ class GeneratedProtocolMessageType(type): type. """ descriptor = dictionary[GeneratedProtocolMessageType._DESCRIPTOR_KEY] - - cls._decoders_by_tag = {} - cls._extensions_by_name = {} - cls._extensions_by_number = {} - if (descriptor.has_options and - descriptor.GetOptions().message_set_wire_format): - cls._decoders_by_tag[decoder.MESSAGE_SET_ITEM_TAG] = ( - decoder.MessageSetItemDecoder(cls._extensions_by_number)) - - # We act as a "friend" class of the descriptor, setting - # its _concrete_class attribute the first time we use a - # given descriptor to initialize a concrete protocol message - # class. We also attach stuff to each FieldDescriptor for quick - # lookup later on. - concrete_class_attr_name = '_concrete_class' - if not hasattr(descriptor, concrete_class_attr_name): - setattr(descriptor, concrete_class_attr_name, cls) - for field in descriptor.fields: - _AttachFieldHelpers(cls, field) - - _AddEnumValues(descriptor, cls) - _AddInitMethod(descriptor, cls) - _AddPropertiesForFields(descriptor, cls) - _AddPropertiesForExtensions(descriptor, cls) - _AddStaticMethods(cls) - _AddMessageMethods(descriptor, cls) - _AddPrivateHelperMethods(cls) + _InitMessage(descriptor, cls) superclass = super(GeneratedProtocolMessageType, cls) superclass.__init__(name, bases, dictionary) - - -# Stateless helpers for GeneratedProtocolMessageType below. -# Outside clients should not access these directly. -# -# I opted not to make any of these methods on the metaclass, to make it more -# clear that I'm not really using any state there and to keep clients from -# thinking that they have direct access to these construction helpers. - - -def _PropertyName(proto_field_name): - """Returns the name of the public property attribute which - clients can use to get and (in some cases) set the value - of a protocol message field. - - Args: - proto_field_name: The protocol message field name, exactly - as it appears (or would appear) in a .proto file. - """ - # TODO(robinson): Escape Python keywords (e.g., yield), and test this support. - # nnorwitz makes my day by writing: - # """ - # FYI. See the keyword module in the stdlib. This could be as simple as: - # - # if keyword.iskeyword(proto_field_name): - # return proto_field_name + "_" - # return proto_field_name - # """ - # Kenton says: The above is a BAD IDEA. People rely on being able to use - # getattr() and setattr() to reflectively manipulate field values. If we - # rename the properties, then every such user has to also make sure to apply - # the same transformation. Note that currently if you name a field "yield", - # you can still access it just fine using getattr/setattr -- it's not even - # that cumbersome to do so. - # TODO(kenton): Remove this method entirely if/when everyone agrees with my - # position. - return proto_field_name - - -def _VerifyExtensionHandle(message, extension_handle): - """Verify that the given extension handle is valid.""" - - if not isinstance(extension_handle, _FieldDescriptor): - raise KeyError('HasExtension() expects an extension handle, got: %s' % - extension_handle) - - if not extension_handle.is_extension: - raise KeyError('"%s" is not an extension.' % extension_handle.full_name) - - if extension_handle.containing_type is not message.DESCRIPTOR: - raise KeyError('Extension "%s" extends message type "%s", but this ' - 'message is of type "%s".' % - (extension_handle.full_name, - extension_handle.containing_type.full_name, - message.DESCRIPTOR.full_name)) - - -def _AddSlots(message_descriptor, dictionary): - """Adds a __slots__ entry to dictionary, containing the names of all valid - attributes for this message type. - - Args: - message_descriptor: A Descriptor instance describing this message type. - dictionary: Class dictionary to which we'll add a '__slots__' entry. - """ - dictionary['__slots__'] = ['_cached_byte_size', - '_cached_byte_size_dirty', - '_fields', - '_is_present_in_parent', - '_listener', - '_listener_for_children', - '__weakref__'] - - -def _IsMessageSetExtension(field): - return (field.is_extension and - field.containing_type.has_options and - field.containing_type.GetOptions().message_set_wire_format and - field.type == _FieldDescriptor.TYPE_MESSAGE and - field.message_type == field.extension_scope and - field.label == _FieldDescriptor.LABEL_OPTIONAL) - - -def _AttachFieldHelpers(cls, field_descriptor): - is_repeated = (field_descriptor.label == _FieldDescriptor.LABEL_REPEATED) - is_packed = (field_descriptor.has_options and - field_descriptor.GetOptions().packed) - - if _IsMessageSetExtension(field_descriptor): - field_encoder = encoder.MessageSetItemEncoder(field_descriptor.number) - sizer = encoder.MessageSetItemSizer(field_descriptor.number) - else: - field_encoder = type_checkers.TYPE_TO_ENCODER[field_descriptor.type]( - field_descriptor.number, is_repeated, is_packed) - sizer = type_checkers.TYPE_TO_SIZER[field_descriptor.type]( - field_descriptor.number, is_repeated, is_packed) - - field_descriptor._encoder = field_encoder - field_descriptor._sizer = sizer - field_descriptor._default_constructor = _DefaultValueConstructorForField( - field_descriptor) - - def AddDecoder(wiretype, is_packed): - tag_bytes = encoder.TagBytes(field_descriptor.number, wiretype) - cls._decoders_by_tag[tag_bytes] = ( - type_checkers.TYPE_TO_DECODER[field_descriptor.type]( - field_descriptor.number, is_repeated, is_packed, - field_descriptor, field_descriptor._default_constructor)) - - AddDecoder(type_checkers.FIELD_TYPE_TO_WIRE_TYPE[field_descriptor.type], - False) - - if is_repeated and wire_format.IsTypePackable(field_descriptor.type): - # To support wire compatibility of adding packed = true, add a decoder for - # packed values regardless of the field's options. - AddDecoder(wire_format.WIRETYPE_LENGTH_DELIMITED, True) - - -def _AddClassAttributesForNestedExtensions(descriptor, dictionary): - extension_dict = descriptor.extensions_by_name - for extension_name, extension_field in extension_dict.iteritems(): - assert extension_name not in dictionary - dictionary[extension_name] = extension_field - - -def _AddEnumValues(descriptor, cls): - """Sets class-level attributes for all enum fields defined in this message. - - Args: - descriptor: Descriptor object for this message type. - cls: Class we're constructing for this message type. - """ - for enum_type in descriptor.enum_types: - for enum_value in enum_type.values: - setattr(cls, enum_value.name, enum_value.number) - - -def _DefaultValueConstructorForField(field): - """Returns a function which returns a default value for a field. - - Args: - field: FieldDescriptor object for this field. - - The returned function has one argument: - message: Message instance containing this field, or a weakref proxy - of same. - - That function in turn returns a default value for this field. The default - value may refer back to |message| via a weak reference. - """ - - if field.label == _FieldDescriptor.LABEL_REPEATED: - if field.default_value != []: - raise ValueError('Repeated field default value not empty list: %s' % ( - field.default_value)) - if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: - # We can't look at _concrete_class yet since it might not have - # been set. (Depends on order in which we initialize the classes). - message_type = field.message_type - def MakeRepeatedMessageDefault(message): - return containers.RepeatedCompositeFieldContainer( - message._listener_for_children, field.message_type) - return MakeRepeatedMessageDefault - else: - type_checker = type_checkers.GetTypeChecker(field.cpp_type, field.type) - def MakeRepeatedScalarDefault(message): - return containers.RepeatedScalarFieldContainer( - message._listener_for_children, type_checker) - return MakeRepeatedScalarDefault - - if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: - # _concrete_class may not yet be initialized. - message_type = field.message_type - def MakeSubMessageDefault(message): - result = message_type._concrete_class() - result._SetListener(message._listener_for_children) - return result - return MakeSubMessageDefault - - def MakeScalarDefault(message): - return field.default_value - return MakeScalarDefault - - -def _AddInitMethod(message_descriptor, cls): - """Adds an __init__ method to cls.""" - fields = message_descriptor.fields - def init(self, **kwargs): - self._cached_byte_size = 0 - self._cached_byte_size_dirty = False - self._fields = {} - self._is_present_in_parent = False - self._listener = message_listener_mod.NullMessageListener() - self._listener_for_children = _Listener(self) - for field_name, field_value in kwargs.iteritems(): - field = _GetFieldByName(message_descriptor, field_name) - if field is None: - raise TypeError("%s() got an unexpected keyword argument '%s'" % - (message_descriptor.name, field_name)) - if field.label == _FieldDescriptor.LABEL_REPEATED: - copy = field._default_constructor(self) - if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: # Composite - for val in field_value: - copy.add().MergeFrom(val) - else: # Scalar - copy.extend(field_value) - self._fields[field] = copy - elif field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: - copy = field._default_constructor(self) - copy.MergeFrom(field_value) - self._fields[field] = copy - else: - setattr(self, field_name, field_value) - - init.__module__ = None - init.__doc__ = None - cls.__init__ = init - - -def _GetFieldByName(message_descriptor, field_name): - """Returns a field descriptor by field name. - - Args: - message_descriptor: A Descriptor describing all fields in message. - field_name: The name of the field to retrieve. - Returns: - The field descriptor associated with the field name. - """ - try: - return message_descriptor.fields_by_name[field_name] - except KeyError: - raise ValueError('Protocol message has no "%s" field.' % field_name) - - -def _AddPropertiesForFields(descriptor, cls): - """Adds properties for all fields in this protocol message type.""" - for field in descriptor.fields: - _AddPropertiesForField(field, cls) - - if descriptor.is_extendable: - # _ExtensionDict is just an adaptor with no state so we allocate a new one - # every time it is accessed. - cls.Extensions = property(lambda self: _ExtensionDict(self)) - - -def _AddPropertiesForField(field, cls): - """Adds a public property for a protocol message field. - Clients can use this property to get and (in the case - of non-repeated scalar fields) directly set the value - of a protocol message field. - - Args: - field: A FieldDescriptor for this field. - cls: The class we're constructing. - """ - # Catch it if we add other types that we should - # handle specially here. - assert _FieldDescriptor.MAX_CPPTYPE == 10 - - constant_name = field.name.upper() + "_FIELD_NUMBER" - setattr(cls, constant_name, field.number) - - if field.label == _FieldDescriptor.LABEL_REPEATED: - _AddPropertiesForRepeatedField(field, cls) - elif field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: - _AddPropertiesForNonRepeatedCompositeField(field, cls) - else: - _AddPropertiesForNonRepeatedScalarField(field, cls) - - -def _AddPropertiesForRepeatedField(field, cls): - """Adds a public property for a "repeated" protocol message field. Clients - can use this property to get the value of the field, which will be either a - _RepeatedScalarFieldContainer or _RepeatedCompositeFieldContainer (see - below). - - Note that when clients add values to these containers, we perform - type-checking in the case of repeated scalar fields, and we also set any - necessary "has" bits as a side-effect. - - Args: - field: A FieldDescriptor for this field. - cls: The class we're constructing. - """ - proto_field_name = field.name - property_name = _PropertyName(proto_field_name) - - def getter(self): - field_value = self._fields.get(field) - if field_value is None: - # Construct a new object to represent this field. - field_value = field._default_constructor(self) - - # Atomically check if another thread has preempted us and, if not, swap - # in the new object we just created. If someone has preempted us, we - # take that object and discard ours. - # WARNING: We are relying on setdefault() being atomic. This is true - # in CPython but we haven't investigated others. This warning appears - # in several other locations in this file. - field_value = self._fields.setdefault(field, field_value) - return field_value - getter.__module__ = None - getter.__doc__ = 'Getter for %s.' % proto_field_name - - # We define a setter just so we can throw an exception with a more - # helpful error message. - def setter(self, new_value): - raise AttributeError('Assignment not allowed to repeated field ' - '"%s" in protocol message object.' % proto_field_name) - - doc = 'Magic attribute generated for "%s" proto field.' % proto_field_name - setattr(cls, property_name, property(getter, setter, doc=doc)) - - -def _AddPropertiesForNonRepeatedScalarField(field, cls): - """Adds a public property for a nonrepeated, scalar protocol message field. - Clients can use this property to get and directly set the value of the field. - Note that when the client sets the value of a field by using this property, - all necessary "has" bits are set as a side-effect, and we also perform - type-checking. - - Args: - field: A FieldDescriptor for this field. - cls: The class we're constructing. - """ - proto_field_name = field.name - property_name = _PropertyName(proto_field_name) - type_checker = type_checkers.GetTypeChecker(field.cpp_type, field.type) - default_value = field.default_value - - def getter(self): - return self._fields.get(field, default_value) - getter.__module__ = None - getter.__doc__ = 'Getter for %s.' % proto_field_name - def setter(self, new_value): - type_checker.CheckValue(new_value) - self._fields[field] = new_value - # Check _cached_byte_size_dirty inline to improve performance, since scalar - # setters are called frequently. - if not self._cached_byte_size_dirty: - self._Modified() - setter.__module__ = None - setter.__doc__ = 'Setter for %s.' % proto_field_name - - # Add a property to encapsulate the getter/setter. - doc = 'Magic attribute generated for "%s" proto field.' % proto_field_name - setattr(cls, property_name, property(getter, setter, doc=doc)) - - -def _AddPropertiesForNonRepeatedCompositeField(field, cls): - """Adds a public property for a nonrepeated, composite protocol message field. - A composite field is a "group" or "message" field. - - Clients can use this property to get the value of the field, but cannot - assign to the property directly. - - Args: - field: A FieldDescriptor for this field. - cls: The class we're constructing. - """ - # TODO(robinson): Remove duplication with similar method - # for non-repeated scalars. - proto_field_name = field.name - property_name = _PropertyName(proto_field_name) - message_type = field.message_type - - def getter(self): - field_value = self._fields.get(field) - if field_value is None: - # Construct a new object to represent this field. - field_value = message_type._concrete_class() - field_value._SetListener(self._listener_for_children) - - # Atomically check if another thread has preempted us and, if not, swap - # in the new object we just created. If someone has preempted us, we - # take that object and discard ours. - # WARNING: We are relying on setdefault() being atomic. This is true - # in CPython but we haven't investigated others. This warning appears - # in several other locations in this file. - field_value = self._fields.setdefault(field, field_value) - return field_value - getter.__module__ = None - getter.__doc__ = 'Getter for %s.' % proto_field_name - - # We define a setter just so we can throw an exception with a more - # helpful error message. - def setter(self, new_value): - raise AttributeError('Assignment not allowed to composite field ' - '"%s" in protocol message object.' % proto_field_name) - - # Add a property to encapsulate the getter. - doc = 'Magic attribute generated for "%s" proto field.' % proto_field_name - setattr(cls, property_name, property(getter, setter, doc=doc)) - - -def _AddPropertiesForExtensions(descriptor, cls): - """Adds properties for all fields in this protocol message type.""" - extension_dict = descriptor.extensions_by_name - for extension_name, extension_field in extension_dict.iteritems(): - constant_name = extension_name.upper() + "_FIELD_NUMBER" - setattr(cls, constant_name, extension_field.number) - - -def _AddStaticMethods(cls): - # TODO(robinson): This probably needs to be thread-safe(?) - def RegisterExtension(extension_handle): - extension_handle.containing_type = cls.DESCRIPTOR - _AttachFieldHelpers(cls, extension_handle) - - # Try to insert our extension, failing if an extension with the same number - # already exists. - actual_handle = cls._extensions_by_number.setdefault( - extension_handle.number, extension_handle) - if actual_handle is not extension_handle: - raise AssertionError( - 'Extensions "%s" and "%s" both try to extend message type "%s" with ' - 'field number %d.' % - (extension_handle.full_name, actual_handle.full_name, - cls.DESCRIPTOR.full_name, extension_handle.number)) - - cls._extensions_by_name[extension_handle.full_name] = extension_handle - - handle = extension_handle # avoid line wrapping - if _IsMessageSetExtension(handle): - # MessageSet extension. Also register under type name. - cls._extensions_by_name[ - extension_handle.message_type.full_name] = extension_handle - - cls.RegisterExtension = staticmethod(RegisterExtension) - - def FromString(s): - message = cls() - message.MergeFromString(s) - return message - cls.FromString = staticmethod(FromString) - - -def _IsPresent(item): - """Given a (FieldDescriptor, value) tuple from _fields, return true if the - value should be included in the list returned by ListFields().""" - - if item[0].label == _FieldDescriptor.LABEL_REPEATED: - return bool(item[1]) - elif item[0].cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: - return item[1]._is_present_in_parent - else: - return True - - -def _AddListFieldsMethod(message_descriptor, cls): - """Helper for _AddMessageMethods().""" - - def ListFields(self): - all_fields = [item for item in self._fields.iteritems() if _IsPresent(item)] - all_fields.sort(key = lambda item: item[0].number) - return all_fields - - cls.ListFields = ListFields - - -def _AddHasFieldMethod(message_descriptor, cls): - """Helper for _AddMessageMethods().""" - - singular_fields = {} - for field in message_descriptor.fields: - if field.label != _FieldDescriptor.LABEL_REPEATED: - singular_fields[field.name] = field - - def HasField(self, field_name): - try: - field = singular_fields[field_name] - except KeyError: - raise ValueError( - 'Protocol message has no singular "%s" field.' % field_name) - - if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: - value = self._fields.get(field) - return value is not None and value._is_present_in_parent - else: - return field in self._fields - cls.HasField = HasField - - -def _AddClearFieldMethod(message_descriptor, cls): - """Helper for _AddMessageMethods().""" - def ClearField(self, field_name): - try: - field = message_descriptor.fields_by_name[field_name] - except KeyError: - raise ValueError('Protocol message has no "%s" field.' % field_name) - - if field in self._fields: - # Note: If the field is a sub-message, its listener will still point - # at us. That's fine, because the worst than can happen is that it - # will call _Modified() and invalidate our byte size. Big deal. - del self._fields[field] - - # Always call _Modified() -- even if nothing was changed, this is - # a mutating method, and thus calling it should cause the field to become - # present in the parent message. - self._Modified() - - cls.ClearField = ClearField - - -def _AddClearExtensionMethod(cls): - """Helper for _AddMessageMethods().""" - def ClearExtension(self, extension_handle): - _VerifyExtensionHandle(self, extension_handle) - - # Similar to ClearField(), above. - if extension_handle in self._fields: - del self._fields[extension_handle] - self._Modified() - cls.ClearExtension = ClearExtension - - -def _AddClearMethod(message_descriptor, cls): - """Helper for _AddMessageMethods().""" - def Clear(self): - # Clear fields. - self._fields = {} - self._Modified() - cls.Clear = Clear - - -def _AddHasExtensionMethod(cls): - """Helper for _AddMessageMethods().""" - def HasExtension(self, extension_handle): - _VerifyExtensionHandle(self, extension_handle) - if extension_handle.label == _FieldDescriptor.LABEL_REPEATED: - raise KeyError('"%s" is repeated.' % extension_handle.full_name) - - if extension_handle.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: - value = self._fields.get(extension_handle) - return value is not None and value._is_present_in_parent - else: - return extension_handle in self._fields - cls.HasExtension = HasExtension - - -def _AddEqualsMethod(message_descriptor, cls): - """Helper for _AddMessageMethods().""" - def __eq__(self, other): - if (not isinstance(other, message_mod.Message) or - other.DESCRIPTOR != self.DESCRIPTOR): - return False - - if self is other: - return True - - return self.ListFields() == other.ListFields() - - cls.__eq__ = __eq__ - - -def _AddStrMethod(message_descriptor, cls): - """Helper for _AddMessageMethods().""" - def __str__(self): - return text_format.MessageToString(self) - cls.__str__ = __str__ - - -def _AddSetListenerMethod(cls): - """Helper for _AddMessageMethods().""" - def SetListener(self, listener): - if listener is None: - self._listener = message_listener_mod.NullMessageListener() - else: - self._listener = listener - cls._SetListener = SetListener - - -def _BytesForNonRepeatedElement(value, field_number, field_type): - """Returns the number of bytes needed to serialize a non-repeated element. - The returned byte count includes space for tag information and any - other additional space associated with serializing value. - - Args: - value: Value we're serializing. - field_number: Field number of this value. (Since the field number - is stored as part of a varint-encoded tag, this has an impact - on the total bytes required to serialize the value). - field_type: The type of the field. One of the TYPE_* constants - within FieldDescriptor. - """ - try: - fn = type_checkers.TYPE_TO_BYTE_SIZE_FN[field_type] - return fn(field_number, value) - except KeyError: - raise message_mod.EncodeError('Unrecognized field type: %d' % field_type) - - -def _AddByteSizeMethod(message_descriptor, cls): - """Helper for _AddMessageMethods().""" - - def ByteSize(self): - if not self._cached_byte_size_dirty: - return self._cached_byte_size - - size = 0 - for field_descriptor, field_value in self.ListFields(): - size += field_descriptor._sizer(field_value) - - self._cached_byte_size = size - self._cached_byte_size_dirty = False - self._listener_for_children.dirty = False - return size - - cls.ByteSize = ByteSize - - -def _AddSerializeToStringMethod(message_descriptor, cls): - """Helper for _AddMessageMethods().""" - - def SerializeToString(self): - # Check if the message has all of its required fields set. - errors = [] - if not self.IsInitialized(): - raise message_mod.EncodeError( - 'Message is missing required fields: ' + - ','.join(self.FindInitializationErrors())) - return self.SerializePartialToString() - cls.SerializeToString = SerializeToString - - -def _AddSerializePartialToStringMethod(message_descriptor, cls): - """Helper for _AddMessageMethods().""" - - def SerializePartialToString(self): - out = StringIO() - self._InternalSerialize(out.write) - return out.getvalue() - cls.SerializePartialToString = SerializePartialToString - - def InternalSerialize(self, write_bytes): - for field_descriptor, field_value in self.ListFields(): - field_descriptor._encoder(write_bytes, field_value) - cls._InternalSerialize = InternalSerialize - - -def _AddMergeFromStringMethod(message_descriptor, cls): - """Helper for _AddMessageMethods().""" - def MergeFromString(self, serialized): - length = len(serialized) - try: - if self._InternalParse(serialized, 0, length) != length: - # The only reason _InternalParse would return early is if it - # encountered an end-group tag. - raise message_mod.DecodeError('Unexpected end-group tag.') - except IndexError: - raise message_mod.DecodeError('Truncated message.') - except struct.error, e: - raise message_mod.DecodeError(e) - return length # Return this for legacy reasons. - cls.MergeFromString = MergeFromString - - local_ReadTag = decoder.ReadTag - local_SkipField = decoder.SkipField - decoders_by_tag = cls._decoders_by_tag - - def InternalParse(self, buffer, pos, end): - self._Modified() - field_dict = self._fields - while pos != end: - (tag_bytes, new_pos) = local_ReadTag(buffer, pos) - field_decoder = decoders_by_tag.get(tag_bytes) - if field_decoder is None: - new_pos = local_SkipField(buffer, new_pos, end, tag_bytes) - if new_pos == -1: - return pos - pos = new_pos - else: - pos = field_decoder(buffer, new_pos, end, self, field_dict) - return pos - cls._InternalParse = InternalParse - - -def _AddIsInitializedMethod(message_descriptor, cls): - """Adds the IsInitialized and FindInitializationError methods to the - protocol message class.""" - - required_fields = [field for field in message_descriptor.fields - if field.label == _FieldDescriptor.LABEL_REQUIRED] - - def IsInitialized(self, errors=None): - """Checks if all required fields of a message are set. - - Args: - errors: A list which, if provided, will be populated with the field - paths of all missing required fields. - - Returns: - True iff the specified message has all required fields set. - """ - - # Performance is critical so we avoid HasField() and ListFields(). - - for field in required_fields: - if (field not in self._fields or - (field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE and - not self._fields[field]._is_present_in_parent)): - if errors is not None: - errors.extend(self.FindInitializationErrors()) - return False - - for field, value in self._fields.iteritems(): - if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: - if field.label == _FieldDescriptor.LABEL_REPEATED: - for element in value: - if not element.IsInitialized(): - if errors is not None: - errors.extend(self.FindInitializationErrors()) - return False - elif value._is_present_in_parent and not value.IsInitialized(): - if errors is not None: - errors.extend(self.FindInitializationErrors()) - return False - - return True - - cls.IsInitialized = IsInitialized - - def FindInitializationErrors(self): - """Finds required fields which are not initialized. - - Returns: - A list of strings. Each string is a path to an uninitialized field from - the top-level message, e.g. "foo.bar[5].baz". - """ - - errors = [] # simplify things - - for field in required_fields: - if not self.HasField(field.name): - errors.append(field.name) - - for field, value in self.ListFields(): - if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: - if field.is_extension: - name = "(%s)" % field.full_name - else: - name = field.name - - if field.label == _FieldDescriptor.LABEL_REPEATED: - for i in xrange(len(value)): - element = value[i] - prefix = "%s[%d]." % (name, i) - sub_errors = element.FindInitializationErrors() - errors += [ prefix + error for error in sub_errors ] - else: - prefix = name + "." - sub_errors = value.FindInitializationErrors() - errors += [ prefix + error for error in sub_errors ] - - return errors - - cls.FindInitializationErrors = FindInitializationErrors - - -def _AddMergeFromMethod(cls): - LABEL_REPEATED = _FieldDescriptor.LABEL_REPEATED - CPPTYPE_MESSAGE = _FieldDescriptor.CPPTYPE_MESSAGE - - def MergeFrom(self, msg): - if not isinstance(msg, cls): - raise TypeError( - "Parameter to MergeFrom() must be instance of same class.") - - assert msg is not self - self._Modified() - - fields = self._fields - - for field, value in msg._fields.iteritems(): - if field.label == LABEL_REPEATED: - field_value = fields.get(field) - if field_value is None: - # Construct a new object to represent this field. - field_value = field._default_constructor(self) - fields[field] = field_value - field_value.MergeFrom(value) - elif field.cpp_type == CPPTYPE_MESSAGE: - if value._is_present_in_parent: - field_value = fields.get(field) - if field_value is None: - # Construct a new object to represent this field. - field_value = field._default_constructor(self) - fields[field] = field_value - field_value.MergeFrom(value) - else: - self._fields[field] = value - cls.MergeFrom = MergeFrom - - -def _AddMessageMethods(message_descriptor, cls): - """Adds implementations of all Message methods to cls.""" - _AddListFieldsMethod(message_descriptor, cls) - _AddHasFieldMethod(message_descriptor, cls) - _AddClearFieldMethod(message_descriptor, cls) - if message_descriptor.is_extendable: - _AddClearExtensionMethod(cls) - _AddHasExtensionMethod(cls) - _AddClearMethod(message_descriptor, cls) - _AddEqualsMethod(message_descriptor, cls) - _AddStrMethod(message_descriptor, cls) - _AddSetListenerMethod(cls) - _AddByteSizeMethod(message_descriptor, cls) - _AddSerializeToStringMethod(message_descriptor, cls) - _AddSerializePartialToStringMethod(message_descriptor, cls) - _AddMergeFromStringMethod(message_descriptor, cls) - _AddIsInitializedMethod(message_descriptor, cls) - _AddMergeFromMethod(cls) - - -def _AddPrivateHelperMethods(cls): - """Adds implementation of private helper methods to cls.""" - - def Modified(self): - """Sets the _cached_byte_size_dirty bit to true, - and propagates this to our listener iff this was a state change. - """ - - # Note: Some callers check _cached_byte_size_dirty before calling - # _Modified() as an extra optimization. So, if this method is ever - # changed such that it does stuff even when _cached_byte_size_dirty is - # already true, the callers need to be updated. - if not self._cached_byte_size_dirty: - self._cached_byte_size_dirty = True - self._listener_for_children.dirty = True - self._is_present_in_parent = True - self._listener.Modified() - - cls._Modified = Modified - cls.SetInParent = Modified - - -class _Listener(object): - - """MessageListener implementation that a parent message registers with its - child message. - - In order to support semantics like: - - foo.bar.baz.qux = 23 - assert foo.HasField('bar') - - ...child objects must have back references to their parents. - This helper class is at the heart of this support. - """ - - def __init__(self, parent_message): - """Args: - parent_message: The message whose _Modified() method we should call when - we receive Modified() messages. - """ - # This listener establishes a back reference from a child (contained) object - # to its parent (containing) object. We make this a weak reference to avoid - # creating cyclic garbage when the client finishes with the 'parent' object - # in the tree. - if isinstance(parent_message, weakref.ProxyType): - self._parent_message_weakref = parent_message - else: - self._parent_message_weakref = weakref.proxy(parent_message) - - # As an optimization, we also indicate directly on the listener whether - # or not the parent message is dirty. This way we can avoid traversing - # up the tree in the common case. - self.dirty = False - - def Modified(self): - if self.dirty: - return - try: - # Propagate the signal to our parents iff this is the first field set. - self._parent_message_weakref._Modified() - except ReferenceError: - # We can get here if a client has kept a reference to a child object, - # and is now setting a field on it, but the child's parent has been - # garbage-collected. This is not an error. - pass - - -# TODO(robinson): Move elsewhere? This file is getting pretty ridiculous... -# TODO(robinson): Unify error handling of "unknown extension" crap. -# TODO(robinson): Support iteritems()-style iteration over all -# extensions with the "has" bits turned on? -class _ExtensionDict(object): - - """Dict-like container for supporting an indexable "Extensions" - field on proto instances. - - Note that in all cases we expect extension handles to be - FieldDescriptors. - """ - - def __init__(self, extended_message): - """extended_message: Message instance for which we are the Extensions dict. - """ - - self._extended_message = extended_message - - def __getitem__(self, extension_handle): - """Returns the current value of the given extension handle.""" - - _VerifyExtensionHandle(self._extended_message, extension_handle) - - result = self._extended_message._fields.get(extension_handle) - if result is not None: - return result - - if extension_handle.label == _FieldDescriptor.LABEL_REPEATED: - result = extension_handle._default_constructor(self._extended_message) - elif extension_handle.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: - result = extension_handle.message_type._concrete_class() - try: - result._SetListener(self._extended_message._listener_for_children) - except ReferenceError: - pass - else: - # Singular scalar -- just return the default without inserting into the - # dict. - return extension_handle.default_value - - # Atomically check if another thread has preempted us and, if not, swap - # in the new object we just created. If someone has preempted us, we - # take that object and discard ours. - # WARNING: We are relying on setdefault() being atomic. This is true - # in CPython but we haven't investigated others. This warning appears - # in several other locations in this file. - result = self._extended_message._fields.setdefault( - extension_handle, result) - - return result - - def __eq__(self, other): - if not isinstance(other, self.__class__): - return False - - my_fields = self._extended_message.ListFields() - other_fields = other._extended_message.ListFields() - - # Get rid of non-extension fields. - my_fields = [ field for field in my_fields if field.is_extension ] - other_fields = [ field for field in other_fields if field.is_extension ] - - return my_fields == other_fields - - def __ne__(self, other): - return not self == other - - # Note that this is only meaningful for non-repeated, scalar extension - # fields. Note also that we may have to call _Modified() when we do - # successfully set a field this way, to set any necssary "has" bits in the - # ancestors of the extended message. - def __setitem__(self, extension_handle, value): - """If extension_handle specifies a non-repeated, scalar extension - field, sets the value of that field. - """ - - _VerifyExtensionHandle(self._extended_message, extension_handle) - - if (extension_handle.label == _FieldDescriptor.LABEL_REPEATED or - extension_handle.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE): - raise TypeError( - 'Cannot assign to extension "%s" because it is a repeated or ' - 'composite type.' % extension_handle.full_name) - - # It's slightly wasteful to lookup the type checker each time, - # but we expect this to be a vanishingly uncommon case anyway. - type_checker = type_checkers.GetTypeChecker( - extension_handle.cpp_type, extension_handle.type) - type_checker.CheckValue(value) - self._extended_message._fields[extension_handle] = value - self._extended_message._Modified() - - def _FindExtensionByName(self, name): - """Tries to find a known extension with the specified name. - - Args: - name: Extension full name. - - Returns: - Extension field descriptor. - """ - return self._extended_message._extensions_by_name.get(name, None) diff --git a/third_party/protobuf/python/google/protobuf/text_format.py b/third_party/protobuf/python/google/protobuf/text_format.py index cc6ac90..c3a1cf6 100755 --- a/third_party/protobuf/python/google/protobuf/text_format.py +++ b/third_party/protobuf/python/google/protobuf/text_format.py @@ -53,24 +53,26 @@ class ParseError(Exception): """Thrown in case of ASCII parsing error.""" -def MessageToString(message): +def MessageToString(message, as_utf8=False, as_one_line=False): out = cStringIO.StringIO() - PrintMessage(message, out) + PrintMessage(message, out, as_utf8=as_utf8, as_one_line=as_one_line) result = out.getvalue() out.close() + if as_one_line: + return result.rstrip() return result -def PrintMessage(message, out, indent = 0): +def PrintMessage(message, out, indent=0, as_utf8=False, as_one_line=False): for field, value in message.ListFields(): if field.label == descriptor.FieldDescriptor.LABEL_REPEATED: for element in value: - PrintField(field, element, out, indent) + PrintField(field, element, out, indent, as_utf8, as_one_line) else: - PrintField(field, value, out, indent) + PrintField(field, value, out, indent, as_utf8, as_one_line) -def PrintField(field, value, out, indent = 0): +def PrintField(field, value, out, indent=0, as_utf8=False, as_one_line=False): """Print a single field name/value pair. For repeated fields, the value should be a single element.""" @@ -96,23 +98,35 @@ def PrintField(field, value, out, indent = 0): # don't include it. out.write(': ') - PrintFieldValue(field, value, out, indent) - out.write('\n') + PrintFieldValue(field, value, out, indent, as_utf8, as_one_line) + if as_one_line: + out.write(' ') + else: + out.write('\n') -def PrintFieldValue(field, value, out, indent = 0): +def PrintFieldValue(field, value, out, indent=0, + as_utf8=False, as_one_line=False): """Print a single field value (not including name). For repeated fields, the value should be a single element.""" if field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE: - out.write(' {\n') - PrintMessage(value, out, indent + 2) - out.write(' ' * indent + '}') + if as_one_line: + out.write(' { ') + PrintMessage(value, out, indent, as_utf8, as_one_line) + out.write('}') + else: + out.write(' {\n') + PrintMessage(value, out, indent + 2, as_utf8, as_one_line) + out.write(' ' * indent + '}') elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_ENUM: out.write(field.enum_type.values_by_number[value].name) elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_STRING: out.write('\"') - out.write(_CEscape(value)) + if type(value) is unicode: + out.write(_CEscape(value.encode('utf-8'), as_utf8)) + else: + out.write(_CEscape(value, as_utf8)) out.write('\"') elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_BOOL: if value: @@ -208,7 +222,7 @@ def _MergeField(tokenizer, message): sub_message = message.Extensions[field] else: sub_message = getattr(message, field.name) - sub_message.SetInParent() + sub_message.SetInParent() while not tokenizer.TryConsume(end_token): if tokenizer.AtEnd(): @@ -334,10 +348,10 @@ class _Tokenizer(object): Returns: True iff the end was reached. """ - return not self._lines and not self._current_line + return self.token == '' def _PopLine(self): - while not self._current_line: + while len(self._current_line) <= self._column: if not self._lines: self._current_line = '' return @@ -348,11 +362,10 @@ class _Tokenizer(object): def _SkipWhitespace(self): while True: self._PopLine() - match = re.match(self._WHITESPACE, self._current_line) + match = self._WHITESPACE.match(self._current_line, self._column) if not match: break length = len(match.group(0)) - self._current_line = self._current_line[length:] self._column += length def TryConsume(self, token): @@ -402,7 +415,7 @@ class _Tokenizer(object): ParseError: If an identifier couldn't be consumed. """ result = self.token - if not re.match(self._IDENTIFIER, result): + if not self._IDENTIFIER.match(result): raise self._ParseError('Expected identifier.') self.NextToken() return result @@ -481,13 +494,13 @@ class _Tokenizer(object): ParseError: If a floating point number couldn't be consumed. """ text = self.token - if re.match(self._FLOAT_INFINITY, text): + if self._FLOAT_INFINITY.match(text): self.NextToken() if text.startswith('-'): return -_INFINITY return _INFINITY - if re.match(self._FLOAT_NAN, text): + if self._FLOAT_NAN.match(text): self.NextToken() return _NAN @@ -507,10 +520,10 @@ class _Tokenizer(object): Raises: ParseError: If a boolean value couldn't be consumed. """ - if self.token == 'true': + if self.token in ('true', 't', '1'): self.NextToken() return True - elif self.token == 'false': + elif self.token in ('false', 'f', '0'): self.NextToken() return False else: @@ -525,7 +538,11 @@ class _Tokenizer(object): Raises: ParseError: If a string value couldn't be consumed. """ - return unicode(self.ConsumeByteString(), 'utf-8') + bytes = self.ConsumeByteString() + try: + return unicode(bytes, 'utf-8') + except UnicodeDecodeError, e: + raise self._StringParseError(e) def ConsumeByteString(self): """Consumes a byte array value. @@ -609,7 +626,7 @@ class _Tokenizer(object): def _ParseError(self, message): """Creates and *returns* a ParseError for the current token.""" return ParseError('%d:%d : %s' % ( - self._line + 1, self._column + 1, message)) + self._line + 1, self._column - len(self.token) + 1, message)) def _IntegerParseError(self, e): return self._ParseError('Couldn\'t parse integer: ' + str(e)) @@ -617,27 +634,27 @@ class _Tokenizer(object): def _FloatParseError(self, e): return self._ParseError('Couldn\'t parse number: ' + str(e)) + def _StringParseError(self, e): + return self._ParseError('Couldn\'t parse string: ' + str(e)) + def NextToken(self): """Reads the next meaningful token.""" self._previous_line = self._line self._previous_column = self._column - if self.AtEnd(): - self.token = '' - return + self._column += len(self.token) + self._SkipWhitespace() - # Make sure there is data to work on. - self._PopLine() + if not self._lines and len(self._current_line) <= self._column: + self.token = '' + return - match = re.match(self._TOKEN, self._current_line) + match = self._TOKEN.match(self._current_line, self._column) if match: token = match.group(0) - self._current_line = self._current_line[len(token):] self.token = token else: - self.token = self._current_line[0] - self._current_line = self._current_line[1:] - self._SkipWhitespace() + self.token = self._current_line[self._column] # text.encode('string_escape') does not seem to satisfy our needs as it @@ -645,7 +662,7 @@ class _Tokenizer(object): # C++ unescaping function allows hex escapes to be any length. So, # "\0011".encode('string_escape') ends up being "\\x011", which will be # decoded in C++ as a single-character string with char code 0x11. -def _CEscape(text): +def _CEscape(text, as_utf8): def escape(c): o = ord(c) if o == 10: return r"\n" # optional escape @@ -656,12 +673,13 @@ def _CEscape(text): if o == 34: return r'\"' # necessary escape if o == 92: return r"\\" # necessary escape - if o >= 127 or o < 32: return "\\%03o" % o # necessary escapes + # necessary escapes + if not as_utf8 and (o >= 127 or o < 32): return "\\%03o" % o return c return "".join([escape(c) for c in text]) -_CUNESCAPE_HEX = re.compile('\\\\x([0-9a-fA-F]{2}|[0-9a-f-A-F])') +_CUNESCAPE_HEX = re.compile('\\\\x([0-9a-fA-F]{2}|[0-9a-fA-F])') def _CUnescape(text): diff --git a/third_party/protobuf/python/setup.py b/third_party/protobuf/python/setup.py index 8c97439..53e8b4a 100755 --- a/third_party/protobuf/python/setup.py +++ b/third_party/protobuf/python/setup.py @@ -7,7 +7,7 @@ from ez_setup import use_setuptools use_setuptools() -from setuptools import setup +from setuptools import setup, Extension from distutils.spawn import find_executable import sys import os @@ -20,6 +20,10 @@ if os.path.exists("../src/protoc"): protoc = "../src/protoc" elif os.path.exists("../src/protoc.exe"): protoc = "../src/protoc.exe" +elif os.path.exists("../vsprojects/Debug/protoc.exe"): + protoc = "../vsprojects/Debug/protoc.exe" +elif os.path.exists("../vsprojects/Release/protoc.exe"): + protoc = "../vsprojects/Release/protoc.exe" else: protoc = find_executable("protoc") @@ -56,6 +60,7 @@ def MakeTestSuite(): del sys.modules['google'] generate_proto("../src/google/protobuf/unittest.proto") + generate_proto("../src/google/protobuf/unittest_custom_options.proto") generate_proto("../src/google/protobuf/unittest_import.proto") generate_proto("../src/google/protobuf/unittest_mset.proto") generate_proto("../src/google/protobuf/unittest_no_generic_services.proto") @@ -90,33 +95,55 @@ if __name__ == '__main__': for (dirpath, dirnames, filenames) in os.walk("."): for filename in filenames: filepath = os.path.join(dirpath, filename) - if filepath.endswith("_pb2.py") or filepath.endswith(".pyc"): + if filepath.endswith("_pb2.py") or filepath.endswith(".pyc") or \ + filepath.endswith(".so") or filepath.endswith(".o"): os.remove(filepath) else: # Generate necessary .proto file if it doesn't exist. # TODO(kenton): Maybe we should hook this into a distutils command? generate_proto("../src/google/protobuf/descriptor.proto") + generate_proto("../src/google/protobuf/compiler/plugin.proto") + + ext_module_list = [] + + # C++ implementation extension + if os.getenv("PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION", "python") == "cpp": + print "Using EXPERIMENTAL C++ Implmenetation." + ext_module_list.append(Extension( + "google.protobuf.internal._net_proto2___python", + [ "google/protobuf/pyext/python_descriptor.cc", + "google/protobuf/pyext/python_protobuf.cc", + "google/protobuf/pyext/python-proto2.cc" ], + include_dirs = [ "../src", ".", ], + libraries = [ "protobuf" ], + runtime_library_dirs = [ "../src/.libs" ], + library_dirs = [ "../src/.libs" ])) setup(name = 'protobuf', - version = '2.3.1-pre', + version = '2.4.0-pre', packages = [ 'google' ], namespace_packages = [ 'google' ], test_suite = 'setup.MakeTestSuite', # Must list modules explicitly so that we don't install tests. py_modules = [ + 'google.protobuf.internal.api_implementation', 'google.protobuf.internal.containers', + 'google.protobuf.internal.cpp_message', 'google.protobuf.internal.decoder', 'google.protobuf.internal.encoder', 'google.protobuf.internal.message_listener', + 'google.protobuf.internal.python_message', 'google.protobuf.internal.type_checkers', 'google.protobuf.internal.wire_format', 'google.protobuf.descriptor', 'google.protobuf.descriptor_pb2', + 'google.protobuf.compiler.plugin_pb2', 'google.protobuf.message', 'google.protobuf.reflection', 'google.protobuf.service', 'google.protobuf.service_reflection', 'google.protobuf.text_format' ], + ext_modules = ext_module_list, url = 'http://code.google.com/p/protobuf/', maintainer = maintainer_email, maintainer_email = 'protobuf@googlegroups.com', diff --git a/third_party/protobuf/src/Makefile.am b/third_party/protobuf/src/Makefile.am index 35f5c0c..327339a 100644 --- a/third_party/protobuf/src/Makefile.am +++ b/third_party/protobuf/src/Makefile.am @@ -77,11 +77,10 @@ nobase_include_HEADERS = \ lib_LTLIBRARIES = libprotobuf-lite.la libprotobuf.la libprotoc.la libprotobuf_lite_la_LIBADD = $(PTHREAD_LIBS) -libprotobuf_lite_la_LDFLAGS = -version-info 6:0:0 -export-dynamic -no-undefined +libprotobuf_lite_la_LDFLAGS = -version-info 7:0:0 -export-dynamic -no-undefined libprotobuf_lite_la_SOURCES = \ google/protobuf/stubs/common.cc \ google/protobuf/stubs/once.cc \ - google/protobuf/stubs/hash.cc \ google/protobuf/stubs/hash.h \ google/protobuf/stubs/map-util.h \ google/protobuf/stubs/stl_util-inl.h \ @@ -96,7 +95,7 @@ libprotobuf_lite_la_SOURCES = \ google/protobuf/io/zero_copy_stream_impl_lite.cc libprotobuf_la_LIBADD = $(PTHREAD_LIBS) -libprotobuf_la_LDFLAGS = -version-info 6:0:0 -export-dynamic -no-undefined +libprotobuf_la_LDFLAGS = -version-info 7:0:0 -export-dynamic -no-undefined libprotobuf_la_SOURCES = \ $(libprotobuf_lite_la_SOURCES) \ google/protobuf/stubs/strutil.cc \ @@ -124,7 +123,7 @@ libprotobuf_la_SOURCES = \ google/protobuf/compiler/parser.cc libprotoc_la_LIBADD = $(PTHREAD_LIBS) libprotobuf.la -libprotoc_la_LDFLAGS = -version-info 6:0:0 -export-dynamic -no-undefined +libprotoc_la_LDFLAGS = -version-info 7:0:0 -export-dynamic -no-undefined libprotoc_la_SOURCES = \ google/protobuf/compiler/code_generator.cc \ google/protobuf/compiler/command_line_interface.cc \ @@ -178,6 +177,8 @@ libprotoc_la_SOURCES = \ google/protobuf/compiler/java/java_primitive_field.h \ google/protobuf/compiler/java/java_service.cc \ google/protobuf/compiler/java/java_service.h \ + google/protobuf/compiler/java/java_string_field.cc \ + google/protobuf/compiler/java/java_string_field.h \ google/protobuf/compiler/python/python_generator.cc bin_PROGRAMS = protoc diff --git a/third_party/protobuf/src/google/protobuf/compiler/code_generator.cc b/third_party/protobuf/src/google/protobuf/compiler/code_generator.cc index 3413a36..455c239 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/code_generator.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/code_generator.cc @@ -42,14 +42,19 @@ namespace protobuf { namespace compiler { CodeGenerator::~CodeGenerator() {} -OutputDirectory::~OutputDirectory() {} +GeneratorContext::~GeneratorContext() {} -io::ZeroCopyOutputStream* OutputDirectory::OpenForInsert( +io::ZeroCopyOutputStream* GeneratorContext::OpenForInsert( const string& filename, const string& insertion_point) { - GOOGLE_LOG(FATAL) << "This OutputDirectory does not support insertion."; + GOOGLE_LOG(FATAL) << "This GeneratorContext does not support insertion."; return NULL; // make compiler happy } +void GeneratorContext::ListParsedFiles( + vector<const FileDescriptor*>* output) { + GOOGLE_LOG(FATAL) << "This GeneratorContext does not support ListParsedFiles"; +} + // Parses a set of comma-delimited name/value pairs. void ParseGeneratorParameter(const string& text, vector<pair<string, string> >* output) { diff --git a/third_party/protobuf/src/google/protobuf/compiler/code_generator.h b/third_party/protobuf/src/google/protobuf/compiler/code_generator.h index ea094cd..252f68d 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/code_generator.h +++ b/third_party/protobuf/src/google/protobuf/compiler/code_generator.h @@ -53,7 +53,7 @@ namespace compiler { // Defined in this file. class CodeGenerator; -class OutputDirectory; +class GeneratorContext; // The abstract interface to a class which generates code implementing a // particular proto file in a particular language. A number of these may @@ -76,7 +76,7 @@ class LIBPROTOC_EXPORT CodeGenerator { // the problem (e.g. "invalid parameter") and returns false. virtual bool Generate(const FileDescriptor* file, const string& parameter, - OutputDirectory* output_directory, + GeneratorContext* generator_context, string* error) const = 0; private: @@ -85,11 +85,12 @@ class LIBPROTOC_EXPORT CodeGenerator { // CodeGenerators generate one or more files in a given directory. This // abstract interface represents the directory to which the CodeGenerator is -// to write. -class LIBPROTOC_EXPORT OutputDirectory { +// to write and other information about the context in which the Generator +// runs. +class LIBPROTOC_EXPORT GeneratorContext { public: - inline OutputDirectory() {} - virtual ~OutputDirectory(); + inline GeneratorContext() {} + virtual ~GeneratorContext(); // Opens the given file, truncating it if it exists, and returns a // ZeroCopyOutputStream that writes to the file. The caller takes ownership @@ -112,10 +113,19 @@ class LIBPROTOC_EXPORT OutputDirectory { virtual io::ZeroCopyOutputStream* OpenForInsert( const string& filename, const string& insertion_point); + // Returns a vector of FileDescriptors for all the files being compiled + // in this run. Useful for languages, such as Go, that treat files + // differently when compiled as a set rather than individually. + virtual void ListParsedFiles(vector<const FileDescriptor*>* output); + private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(OutputDirectory); + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GeneratorContext); }; +// The type GeneratorContext was once called OutputDirectory. This typedef +// provides backward compatibility. +typedef GeneratorContext OutputDirectory; + // Several code generators treat the parameter argument as holding a // list of options separated by commas. This helper function parses // a set of comma-delimited name/value pairs: e.g., diff --git a/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc b/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc index 02c3e0f..1c76994 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc @@ -48,6 +48,9 @@ #include <iostream> #include <ctype.h> +#include <google/protobuf/stubs/hash.h> + +#include <google/protobuf/stubs/common.h> #include <google/protobuf/compiler/importer.h> #include <google/protobuf/compiler/code_generator.h> #include <google/protobuf/compiler/plugin.pb.h> @@ -58,12 +61,10 @@ #include <google/protobuf/dynamic_message.h> #include <google/protobuf/io/zero_copy_stream_impl.h> #include <google/protobuf/io/printer.h> -#include <google/protobuf/stubs/common.h> #include <google/protobuf/stubs/strutil.h> #include <google/protobuf/stubs/substitute.h> #include <google/protobuf/stubs/map-util.h> #include <google/protobuf/stubs/stl_util-inl.h> -#include <google/protobuf/stubs/hash.h> namespace google { @@ -182,7 +183,7 @@ bool TryCreateParentDirectory(const string& prefix, const string& filename) { class CommandLineInterface::ErrorPrinter : public MultiFileErrorCollector, public io::ErrorCollector { public: - ErrorPrinter(ErrorFormat format, DiskSourceTree *tree = NULL) + ErrorPrinter(ErrorFormat format, DiskSourceTree *tree = NULL) : format_(format), tree_(tree) {} ~ErrorPrinter() {} @@ -191,8 +192,8 @@ class CommandLineInterface::ErrorPrinter : public MultiFileErrorCollector, const string& message) { // Print full path when running under MSVS - std::string dfile; - if (format_ == CommandLineInterface::ERROR_FORMAT_MSVS && + string dfile; + if (format_ == CommandLineInterface::ERROR_FORMAT_MSVS && tree_ != NULL && tree_->VirtualFileToDiskFile(filename, &dfile)) { cerr << dfile; @@ -229,12 +230,12 @@ class CommandLineInterface::ErrorPrinter : public MultiFileErrorCollector, // ------------------------------------------------------------------- -// An OutputDirectory implementation that buffers files in memory, then dumps +// A GeneratorContext implementation that buffers files in memory, then dumps // them all to disk on demand. -class CommandLineInterface::MemoryOutputDirectory : public OutputDirectory { +class CommandLineInterface::GeneratorContextImpl : public GeneratorContext { public: - MemoryOutputDirectory(); - ~MemoryOutputDirectory(); + GeneratorContextImpl(const vector<const FileDescriptor*>& parsed_files); + ~GeneratorContextImpl(); // Write all files in the directory to disk at the given output location, // which must end in a '/'. @@ -248,10 +249,13 @@ class CommandLineInterface::MemoryOutputDirectory : public OutputDirectory { // format, unless one has already been written. void AddJarManifest(); - // implements OutputDirectory -------------------------------------- + // implements GeneratorContext -------------------------------------- io::ZeroCopyOutputStream* Open(const string& filename); io::ZeroCopyOutputStream* OpenForInsert( const string& filename, const string& insertion_point); + void ListParsedFiles(vector<const FileDescriptor*>* output) { + *output = parsed_files_; + } private: friend class MemoryOutputStream; @@ -259,14 +263,15 @@ class CommandLineInterface::MemoryOutputDirectory : public OutputDirectory { // map instead of hash_map so that files are written in order (good when // writing zips). map<string, string*> files_; + const vector<const FileDescriptor*>& parsed_files_; bool had_error_; }; class CommandLineInterface::MemoryOutputStream : public io::ZeroCopyOutputStream { public: - MemoryOutputStream(MemoryOutputDirectory* directory, const string& filename); - MemoryOutputStream(MemoryOutputDirectory* directory, const string& filename, + MemoryOutputStream(GeneratorContextImpl* directory, const string& filename); + MemoryOutputStream(GeneratorContextImpl* directory, const string& filename, const string& insertion_point); virtual ~MemoryOutputStream(); @@ -277,7 +282,7 @@ class CommandLineInterface::MemoryOutputStream private: // Where to insert the string when it's done. - MemoryOutputDirectory* directory_; + GeneratorContextImpl* directory_; string filename_; string insertion_point_; @@ -290,14 +295,17 @@ class CommandLineInterface::MemoryOutputStream // ------------------------------------------------------------------- -CommandLineInterface::MemoryOutputDirectory::MemoryOutputDirectory() - : had_error_(false) {} +CommandLineInterface::GeneratorContextImpl::GeneratorContextImpl( + const vector<const FileDescriptor*>& parsed_files) + : parsed_files_(parsed_files), + had_error_(false) { +} -CommandLineInterface::MemoryOutputDirectory::~MemoryOutputDirectory() { +CommandLineInterface::GeneratorContextImpl::~GeneratorContextImpl() { STLDeleteValues(&files_); } -bool CommandLineInterface::MemoryOutputDirectory::WriteAllToDisk( +bool CommandLineInterface::GeneratorContextImpl::WriteAllToDisk( const string& prefix) { if (had_error_) { return false; @@ -372,7 +380,7 @@ bool CommandLineInterface::MemoryOutputDirectory::WriteAllToDisk( return true; } -bool CommandLineInterface::MemoryOutputDirectory::WriteAllToZip( +bool CommandLineInterface::GeneratorContextImpl::WriteAllToZip( const string& filename) { if (had_error_) { return false; @@ -413,7 +421,7 @@ bool CommandLineInterface::MemoryOutputDirectory::WriteAllToZip( return true; } -void CommandLineInterface::MemoryOutputDirectory::AddJarManifest() { +void CommandLineInterface::GeneratorContextImpl::AddJarManifest() { string** map_slot = &files_["META-INF/MANIFEST.MF"]; if (*map_slot == NULL) { *map_slot = new string( @@ -423,13 +431,13 @@ void CommandLineInterface::MemoryOutputDirectory::AddJarManifest() { } } -io::ZeroCopyOutputStream* CommandLineInterface::MemoryOutputDirectory::Open( +io::ZeroCopyOutputStream* CommandLineInterface::GeneratorContextImpl::Open( const string& filename) { return new MemoryOutputStream(this, filename); } io::ZeroCopyOutputStream* -CommandLineInterface::MemoryOutputDirectory::OpenForInsert( +CommandLineInterface::GeneratorContextImpl::OpenForInsert( const string& filename, const string& insertion_point) { return new MemoryOutputStream(this, filename, insertion_point); } @@ -437,14 +445,14 @@ CommandLineInterface::MemoryOutputDirectory::OpenForInsert( // ------------------------------------------------------------------- CommandLineInterface::MemoryOutputStream::MemoryOutputStream( - MemoryOutputDirectory* directory, const string& filename) + GeneratorContextImpl* directory, const string& filename) : directory_(directory), filename_(filename), inner_(new io::StringOutputStream(&data_)) { } CommandLineInterface::MemoryOutputStream::MemoryOutputStream( - MemoryOutputDirectory* directory, const string& filename, + GeneratorContextImpl* directory, const string& filename, const string& insertion_point) : directory_(directory), filename_(filename), @@ -613,11 +621,11 @@ int CommandLineInterface::Run(int argc, const char* const argv[]) { } } - // We construct a separate OutputDirectory for each output location. Note + // We construct a separate GeneratorContext for each output location. Note // that two code generators may output to the same location, in which case - // they should share a single OutputDirectory (so that OpenForInsert() works). - typedef hash_map<string, MemoryOutputDirectory*> OutputDirectoryMap; - OutputDirectoryMap output_directories; + // they should share a single GeneratorContext so that OpenForInsert() works. + typedef hash_map<string, GeneratorContextImpl*> GeneratorContextMap; + GeneratorContextMap output_directories; // Generate output. if (mode_ == MODE_COMPILE) { @@ -627,11 +635,11 @@ int CommandLineInterface::Run(int argc, const char* const argv[]) { !HasSuffixString(output_location, ".jar")) { AddTrailingSlash(&output_location); } - MemoryOutputDirectory** map_slot = &output_directories[output_location]; + GeneratorContextImpl** map_slot = &output_directories[output_location]; if (*map_slot == NULL) { // First time we've seen this output location. - *map_slot = new MemoryOutputDirectory; + *map_slot = new GeneratorContextImpl(parsed_files); } if (!GenerateOutput(parsed_files, output_directives_[i], *map_slot)) { @@ -642,10 +650,10 @@ int CommandLineInterface::Run(int argc, const char* const argv[]) { } // Write all output to disk. - for (OutputDirectoryMap::iterator iter = output_directories.begin(); + for (GeneratorContextMap::iterator iter = output_directories.begin(); iter != output_directories.end(); ++iter) { const string& location = iter->first; - MemoryOutputDirectory* directory = iter->second; + GeneratorContextImpl* directory = iter->second; if (HasSuffixString(location, "/")) { if (!directory->WriteAllToDisk(location)) { STLDeleteValues(&output_directories); @@ -773,7 +781,7 @@ bool CommandLineInterface::ParseArguments(int argc, const char* const argv[]) { // If no --proto_path was given, use the current working directory. if (proto_path_.empty()) { - proto_path_.push_back(make_pair("", ".")); + proto_path_.push_back(make_pair<string, string>("", ".")); } // Check some errror cases. @@ -902,7 +910,7 @@ bool CommandLineInterface::InterpretArgument(const string& name, cerr << disk_path << ": warning: directory does not exist." << endl; } - proto_path_.push_back(make_pair(virtual_path, disk_path)); + proto_path_.push_back(make_pair<string, string>(virtual_path, disk_path)); } } else if (name == "-o" || name == "--descriptor_set_out") { @@ -1107,7 +1115,7 @@ void CommandLineInterface::PrintHelpText() { bool CommandLineInterface::GenerateOutput( const vector<const FileDescriptor*>& parsed_files, const OutputDirective& output_directive, - OutputDirectory* output_directory) { + GeneratorContext* generator_context) { // Call the generator. string error; if (output_directive.generator == NULL) { @@ -1122,7 +1130,7 @@ bool CommandLineInterface::GenerateOutput( if (!GeneratePluginOutput(parsed_files, plugin_name, output_directive.parameter, - output_directory, &error)) { + generator_context, &error)) { cerr << output_directive.name << ": " << error << endl; return false; } @@ -1131,7 +1139,7 @@ bool CommandLineInterface::GenerateOutput( for (int i = 0; i < parsed_files.size(); i++) { if (!output_directive.generator->Generate( parsed_files[i], output_directive.parameter, - output_directory, &error)) { + generator_context, &error)) { // Generator returned an error. cerr << output_directive.name << ": " << parsed_files[i]->name() << ": " << error << endl; @@ -1147,7 +1155,7 @@ bool CommandLineInterface::GeneratePluginOutput( const vector<const FileDescriptor*>& parsed_files, const string& plugin_name, const string& parameter, - OutputDirectory* output_directory, + GeneratorContext* generator_context, string* error) { CodeGeneratorRequest request; CodeGeneratorResponse response; @@ -1190,14 +1198,14 @@ bool CommandLineInterface::GeneratePluginOutput( // We reset current_output to NULL first so that the old file is closed // before the new one is opened. current_output.reset(); - current_output.reset(output_directory->OpenForInsert( + current_output.reset(generator_context->OpenForInsert( output_file.name(), output_file.insertion_point())); } else if (!output_file.name().empty()) { // Starting a new file. Open it. // We reset current_output to NULL first so that the old file is closed // before the new one is opened. current_output.reset(); - current_output.reset(output_directory->Open(output_file.name())); + current_output.reset(generator_context->Open(output_file.name())); } else if (current_output == NULL) { *error = strings::Substitute( "$0: First file chunk returned by plugin did not specify a file name.", diff --git a/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.h b/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.h index d25a50e..0b507d8 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.h +++ b/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.h @@ -56,7 +56,7 @@ template<typename T> class RepeatedPtrField; // repeated_field.h namespace compiler { class CodeGenerator; // code_generator.h -class OutputDirectory; // code_generator.h +class GeneratorContext; // code_generator.h class DiskSourceTree; // importer.h // This class implements the command-line interface to the protocol compiler. @@ -174,7 +174,7 @@ class LIBPROTOC_EXPORT CommandLineInterface { // ----------------------------------------------------------------- class ErrorPrinter; - class MemoryOutputDirectory; + class GeneratorContextImpl; class MemoryOutputStream; // Clear state from previous Run(). @@ -212,11 +212,11 @@ class LIBPROTOC_EXPORT CommandLineInterface { struct OutputDirective; // see below bool GenerateOutput(const vector<const FileDescriptor*>& parsed_files, const OutputDirective& output_directive, - OutputDirectory* output_directory); + GeneratorContext* generator_context); bool GeneratePluginOutput(const vector<const FileDescriptor*>& parsed_files, const string& plugin_name, const string& parameter, - OutputDirectory* output_directory, + GeneratorContext* generator_context, string* error); // Implements --encode and --decode. diff --git a/third_party/protobuf/src/google/protobuf/compiler/command_line_interface_unittest.cc b/third_party/protobuf/src/google/protobuf/compiler/command_line_interface_unittest.cc index bdf37ad..d5b3a1d 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/command_line_interface_unittest.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/command_line_interface_unittest.cc @@ -48,6 +48,7 @@ #include <google/protobuf/compiler/command_line_interface.h> #include <google/protobuf/compiler/code_generator.h> #include <google/protobuf/compiler/mock_code_generator.h> +#include <google/protobuf/compiler/subprocess.h> #include <google/protobuf/io/printer.h> #include <google/protobuf/unittest.pb.h> #include <google/protobuf/testing/file.h> @@ -143,6 +144,10 @@ class CommandLineInterfaceTest : public testing::Test { const string& proto_name, const string& message_name, const string& output_directory); + void ExpectGeneratedWithMultipleInputs(const string& generator_name, + const string& all_proto_names, + const string& proto_name, + const string& message_name); void ExpectGeneratedWithInsertions(const string& generator_name, const string& parameter, const string& insertions, @@ -190,7 +195,7 @@ class CommandLineInterfaceTest::NullCodeGenerator : public CodeGenerator { // implements CodeGenerator ---------------------------------------- bool Generate(const FileDescriptor* file, const string& parameter, - OutputDirectory* output_directory, + GeneratorContext* context, string* error) const { called_ = true; parameter_ = parameter; @@ -251,7 +256,6 @@ void CommandLineInterfaceTest::Run(const string& command) { if (!disallow_plugins_) { cli_.AllowPlugins("prefix-"); - const char* possible_paths[] = { // When building with shared libraries, libtool hides the real executable // in .libs and puts a fake wrapper in the current directory. @@ -353,7 +357,8 @@ void CommandLineInterfaceTest::ExpectGenerated( const string& proto_name, const string& message_name) { MockCodeGenerator::ExpectGenerated( - generator_name, parameter, "", proto_name, message_name, temp_directory_); + generator_name, parameter, "", proto_name, message_name, proto_name, + temp_directory_); } void CommandLineInterfaceTest::ExpectGenerated( @@ -363,10 +368,21 @@ void CommandLineInterfaceTest::ExpectGenerated( const string& message_name, const string& output_directory) { MockCodeGenerator::ExpectGenerated( - generator_name, parameter, "", proto_name, message_name, + generator_name, parameter, "", proto_name, message_name, proto_name, temp_directory_ + "/" + output_directory); } +void CommandLineInterfaceTest::ExpectGeneratedWithMultipleInputs( + const string& generator_name, + const string& all_proto_names, + const string& proto_name, + const string& message_name) { + MockCodeGenerator::ExpectGenerated( + generator_name, "", "", proto_name, message_name, + all_proto_names, + temp_directory_); +} + void CommandLineInterfaceTest::ExpectGeneratedWithInsertions( const string& generator_name, const string& parameter, @@ -375,7 +391,7 @@ void CommandLineInterfaceTest::ExpectGeneratedWithInsertions( const string& message_name) { MockCodeGenerator::ExpectGenerated( generator_name, parameter, insertions, proto_name, message_name, - temp_directory_); + proto_name, temp_directory_); } void CommandLineInterfaceTest::ExpectNullCodeGeneratorCalled( @@ -455,8 +471,44 @@ TEST_F(CommandLineInterfaceTest, MultipleInputs) { "--proto_path=$tmpdir foo.proto bar.proto"); ExpectNoErrors(); - ExpectGenerated("test_generator", "", "foo.proto", "Foo"); - ExpectGenerated("test_generator", "", "bar.proto", "Bar"); + ExpectGeneratedWithMultipleInputs("test_generator", "foo.proto,bar.proto", + "foo.proto", "Foo"); + ExpectGeneratedWithMultipleInputs("test_generator", "foo.proto,bar.proto", + "bar.proto", "Bar"); + ExpectGeneratedWithMultipleInputs("test_plugin", "foo.proto,bar.proto", + "foo.proto", "Foo"); + ExpectGeneratedWithMultipleInputs("test_plugin", "foo.proto,bar.proto", + "bar.proto", "Bar"); +} + +TEST_F(CommandLineInterfaceTest, MultipleInputsWithImport) { + // Test parsing multiple input files with an import of a separate file. + + CreateTempFile("foo.proto", + "syntax = \"proto2\";\n" + "message Foo {}\n"); + CreateTempFile("bar.proto", + "syntax = \"proto2\";\n" + "import \"baz.proto\";\n" + "message Bar {\n" + " optional Baz a = 1;\n" + "}\n"); + CreateTempFile("baz.proto", + "syntax = \"proto2\";\n" + "message Baz {}\n"); + + Run("protocol_compiler --test_out=$tmpdir --plug_out=$tmpdir " + "--proto_path=$tmpdir foo.proto bar.proto"); + + ExpectNoErrors(); + ExpectGeneratedWithMultipleInputs("test_generator", "foo.proto,bar.proto", + "foo.proto", "Foo"); + ExpectGeneratedWithMultipleInputs("test_generator", "foo.proto,bar.proto", + "bar.proto", "Bar"); + ExpectGeneratedWithMultipleInputs("test_plugin", "foo.proto,bar.proto", + "foo.proto", "Foo"); + ExpectGeneratedWithMultipleInputs("test_plugin", "foo.proto,bar.proto", + "bar.proto", "Bar"); } TEST_F(CommandLineInterfaceTest, CreateDirectory) { @@ -515,7 +567,7 @@ TEST_F(CommandLineInterfaceTest, Insert) { "foo.proto", "Foo"); } -#if defined(_WIN32) || defined(__CYGWIN__) +#if defined(_WIN32) TEST_F(CommandLineInterfaceTest, WindowsOutputPath) { // Test that the output path can be a Windows-style path. @@ -1089,9 +1141,8 @@ TEST_F(CommandLineInterfaceTest, GeneratorPluginNotFound) { "--proto_path=$tmpdir error.proto"); #ifdef _WIN32 - ExpectErrorSubstring( - "--badplug_out: prefix-gen-badplug: The system cannot find the file " - "specified."); + ExpectErrorSubstring("--badplug_out: prefix-gen-badplug: " + + Subprocess::Win32ErrorMessage(ERROR_FILE_NOT_FOUND)); #else // Error written to stdout by child process after exec() fails. ExpectErrorSubstring( diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc b/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc index 30b1d2b..bcfa502 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc @@ -79,10 +79,10 @@ class MockErrorCollector : public MultiFileErrorCollector { } }; -class MockOutputDirectory : public OutputDirectory { +class MockGeneratorContext : public GeneratorContext { public: - MockOutputDirectory() {} - ~MockOutputDirectory() { + MockGeneratorContext() {} + ~MockGeneratorContext() { STLDeleteValues(&files_); } @@ -102,7 +102,7 @@ class MockOutputDirectory : public OutputDirectory { "to your CL."; } - // implements OutputDirectory -------------------------------------- + // implements GeneratorContext -------------------------------------- virtual io::ZeroCopyOutputStream* Open(const string& filename) { string** map_slot = &files_[filename]; @@ -130,24 +130,24 @@ TEST(BootstrapTest, GeneratedDescriptorMatches) { ASSERT_TRUE(plugin_proto_file != NULL); CppGenerator generator; - MockOutputDirectory output_directory; + MockGeneratorContext context; string error; string parameter; parameter = "dllexport_decl=LIBPROTOBUF_EXPORT"; ASSERT_TRUE(generator.Generate(proto_file, parameter, - &output_directory, &error)); + &context, &error)); parameter = "dllexport_decl=LIBPROTOC_EXPORT"; ASSERT_TRUE(generator.Generate(plugin_proto_file, parameter, - &output_directory, &error)); - - output_directory.ExpectFileMatches("google/protobuf/descriptor.pb.h", - "google/protobuf/descriptor.pb.h"); - output_directory.ExpectFileMatches("google/protobuf/descriptor.pb.cc", - "google/protobuf/descriptor.pb.cc"); - output_directory.ExpectFileMatches("google/protobuf/compiler/plugin.pb.h", - "google/protobuf/compiler/plugin.pb.h"); - output_directory.ExpectFileMatches("google/protobuf/compiler/plugin.pb.cc", - "google/protobuf/compiler/plugin.pb.cc"); + &context, &error)); + + context.ExpectFileMatches("google/protobuf/descriptor.pb.h", + "google/protobuf/descriptor.pb.h"); + context.ExpectFileMatches("google/protobuf/descriptor.pb.cc", + "google/protobuf/descriptor.pb.cc"); + context.ExpectFileMatches("google/protobuf/compiler/plugin.pb.h", + "google/protobuf/compiler/plugin.pb.h"); + context.ExpectFileMatches("google/protobuf/compiler/plugin.pb.cc", + "google/protobuf/compiler/plugin.pb.cc"); } } // namespace diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_enum_field.cc b/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_enum_field.cc index 91ce493..a369f41 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_enum_field.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_enum_field.cc @@ -85,7 +85,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { "}\n" "inline void $classname$::set_$name$($type$ value) {\n" " GOOGLE_DCHECK($type$_IsValid(value));\n" - " _set_bit($index$);\n" + " set_has_$name$();\n" " $name$_ = value;\n" "}\n"); } diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_file.cc b/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_file.cc index c24ae05..810600b 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_file.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_file.cc @@ -288,6 +288,7 @@ void FileGenerator::GenerateSource(io::Printer* printer) { printer->Print( "// Generated by the protocol buffer compiler. DO NOT EDIT!\n" "\n" + // The generated code calls accessors that might be deprecated. We don't // want the compiler to warn in generated code. "#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION\n" @@ -545,7 +546,7 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) { static const int kBytesPerLine = 40; for (int i = 0; i < file_data.size(); i += kBytesPerLine) { printer->Print("\n \"$data$\"", - "data", CEscape(file_data.substr(i, kBytesPerLine))); + "data", EscapeTrigraphs(CEscape(file_data.substr(i, kBytesPerLine)))); } printer->Print( ", $size$);\n", diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_generator.cc b/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_generator.cc index d67d350..bb84e2a 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_generator.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_generator.cc @@ -53,7 +53,7 @@ CppGenerator::~CppGenerator() {} bool CppGenerator::Generate(const FileDescriptor* file, const string& parameter, - OutputDirectory* output_directory, + GeneratorContext* generator_context, string* error) const { vector<pair<string, string> > options; ParseGeneratorParameter(parameter, &options); @@ -100,7 +100,7 @@ bool CppGenerator::Generate(const FileDescriptor* file, // Generate header. { scoped_ptr<io::ZeroCopyOutputStream> output( - output_directory->Open(basename + ".h")); + generator_context->Open(basename + ".h")); io::Printer printer(output.get(), '$'); file_generator.GenerateHeader(&printer); } @@ -108,7 +108,7 @@ bool CppGenerator::Generate(const FileDescriptor* file, // Generate cc file. { scoped_ptr<io::ZeroCopyOutputStream> output( - output_directory->Open(basename + ".cc")); + generator_context->Open(basename + ".cc")); io::Printer printer(output.get(), '$'); file_generator.GenerateSource(&printer); } diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_generator.h b/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_generator.h index f52e886..a90e84d 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_generator.h +++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_generator.h @@ -57,7 +57,7 @@ class LIBPROTOC_EXPORT CppGenerator : public CodeGenerator { // implements CodeGenerator ---------------------------------------- bool Generate(const FileDescriptor* file, const string& parameter, - OutputDirectory* output_directory, + GeneratorContext* generator_context, string* error) const; private: diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_helpers.cc b/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_helpers.cc index e3df88b..25b05a8 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_helpers.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_helpers.cc @@ -292,7 +292,8 @@ string DefaultValue(const FieldDescriptor* field) { ClassName(field->enum_type(), true), field->default_value_enum()->number()); case FieldDescriptor::CPPTYPE_STRING: - return "\"" + CEscape(field->default_value_string()) + "\""; + return "\"" + EscapeTrigraphs(CEscape(field->default_value_string())) + + "\""; case FieldDescriptor::CPPTYPE_MESSAGE: return FieldMessageTypeName(field) + "::default_instance()"; } @@ -335,6 +336,11 @@ string GlobalShutdownFileName(const string& filename) { return "protobuf_ShutdownFile_" + FilenameIdentifier(filename); } +// Escape C++ trigraphs by escaping question marks to \? +string EscapeTrigraphs(const string& to_escape) { + return StringReplace(to_escape, "?", "\\?", true); +} + } // namespace cpp } // namespace compiler } // namespace protobuf diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_helpers.h b/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_helpers.h index 6a3a523..ac06398 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_helpers.h +++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_helpers.h @@ -112,6 +112,9 @@ string GlobalAssignDescriptorsName(const string& filename); // Return the name of the ShutdownFile() function for a given file. string GlobalShutdownFileName(const string& filename); +// Escape C++ trigraphs by escaping question marks to \? +string EscapeTrigraphs(const string& to_escape); + // Do message classes in this file keep track of unknown fields? inline bool HasUnknownFields(const FileDescriptor *file) { return file->options().optimize_for() != FileOptions::LITE_RUNTIME || diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_message.cc b/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_message.cc index 02b6d20..b836fb6 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_message.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_message.cc @@ -35,6 +35,7 @@ #include <algorithm> #include <google/protobuf/stubs/hash.h> #include <map> +#include <utility> #include <vector> #include <google/protobuf/compiler/cpp/cpp_message.h> #include <google/protobuf/compiler/cpp/cpp_field.h> @@ -143,6 +144,137 @@ static bool HasRequiredFields(const Descriptor* type) { return HasRequiredFields(type, &already_seen); } +// This returns an estimate of the compiler's alignment for the field. This +// can't guarantee to be correct because the generated code could be compiled on +// different systems with different alignment rules. The estimates below assume +// 64-bit pointers. +int EstimateAlignmentSize(const FieldDescriptor* field) { + if (field == NULL) return 0; + if (field->is_repeated()) return 8; + switch (field->cpp_type()) { + case FieldDescriptor::CPPTYPE_BOOL: + return 1; + + case FieldDescriptor::CPPTYPE_INT32: + case FieldDescriptor::CPPTYPE_UINT32: + case FieldDescriptor::CPPTYPE_ENUM: + case FieldDescriptor::CPPTYPE_FLOAT: + return 4; + + case FieldDescriptor::CPPTYPE_INT64: + case FieldDescriptor::CPPTYPE_UINT64: + case FieldDescriptor::CPPTYPE_DOUBLE: + case FieldDescriptor::CPPTYPE_STRING: + case FieldDescriptor::CPPTYPE_MESSAGE: + return 8; + } + GOOGLE_LOG(FATAL) << "Can't get here."; + return -1; // Make compiler happy. +} + +// FieldGroup is just a helper for OptimizePadding below. It holds a vector of +// fields that are grouped together because they have compatible alignment, and +// a preferred location in the final field ordering. +class FieldGroup { + public: + FieldGroup() + : preferred_location_(0) {} + + // A group with a single field. + FieldGroup(float preferred_location, const FieldDescriptor* field) + : preferred_location_(preferred_location), + fields_(1, field) {} + + // Append the fields in 'other' to this group. + void Append(const FieldGroup& other) { + if (other.fields_.empty()) { + return; + } + // Preferred location is the average among all the fields, so we weight by + // the number of fields on each FieldGroup object. + preferred_location_ = + (preferred_location_ * fields_.size() + + (other.preferred_location_ * other.fields_.size())) / + (fields_.size() + other.fields_.size()); + fields_.insert(fields_.end(), other.fields_.begin(), other.fields_.end()); + } + + void SetPreferredLocation(float location) { preferred_location_ = location; } + const vector<const FieldDescriptor*>& fields() const { return fields_; } + + // FieldGroup objects sort by their preferred location. + bool operator<(const FieldGroup& other) const { + return preferred_location_ < other.preferred_location_; + } + + private: + // "preferred_location_" is an estimate of where this group should go in the + // final list of fields. We compute this by taking the average index of each + // field in this group in the original ordering of fields. This is very + // approximate, but should put this group close to where its member fields + // originally went. + float preferred_location_; + vector<const FieldDescriptor*> fields_; + // We rely on the default copy constructor and operator= so this type can be + // used in a vector. +}; + +// Reorder 'fields' so that if the fields are output into a c++ class in the new +// order, the alignment padding is minimized. We try to do this while keeping +// each field as close as possible to its original position so that we don't +// reduce cache locality much for function that access each field in order. +void OptimizePadding(vector<const FieldDescriptor*>* fields) { + // First divide fields into those that align to 1 byte, 4 bytes or 8 bytes. + vector<FieldGroup> aligned_to_1, aligned_to_4, aligned_to_8; + for (int i = 0; i < fields->size(); ++i) { + switch (EstimateAlignmentSize((*fields)[i])) { + case 1: aligned_to_1.push_back(FieldGroup(i, (*fields)[i])); break; + case 4: aligned_to_4.push_back(FieldGroup(i, (*fields)[i])); break; + case 8: aligned_to_8.push_back(FieldGroup(i, (*fields)[i])); break; + default: + GOOGLE_LOG(FATAL) << "Unknown alignment size."; + } + } + + // Now group fields aligned to 1 byte into sets of 4, and treat those like a + // single field aligned to 4 bytes. + for (int i = 0; i < aligned_to_1.size(); i += 4) { + FieldGroup field_group; + for (int j = i; j < aligned_to_1.size() && j < i + 4; ++j) { + field_group.Append(aligned_to_1[j]); + } + aligned_to_4.push_back(field_group); + } + // Sort by preferred location to keep fields as close to their original + // location as possible. + sort(aligned_to_4.begin(), aligned_to_4.end()); + + // Now group fields aligned to 4 bytes (or the 4-field groups created above) + // into pairs, and treat those like a single field aligned to 8 bytes. + for (int i = 0; i < aligned_to_4.size(); i += 2) { + FieldGroup field_group; + for (int j = i; j < aligned_to_4.size() && j < i + 2; ++j) { + field_group.Append(aligned_to_4[j]); + } + if (i == aligned_to_4.size() - 1) { + // Move incomplete 4-byte block to the end. + field_group.SetPreferredLocation(fields->size() + 1); + } + aligned_to_8.push_back(field_group); + } + // Sort by preferred location to keep fields as close to their original + // location as possible. + sort(aligned_to_8.begin(), aligned_to_8.end()); + + // Now pull out all the FieldDescriptors in order. + fields->clear(); + for (int i = 0; i < aligned_to_8.size(); ++i) { + fields->insert(fields->end(), + aligned_to_8[i].fields().begin(), + aligned_to_8[i].fields().end()); + } +} + } // =================================================================== @@ -264,10 +396,20 @@ GenerateFieldAccessorDefinitions(io::Printer* printer) { "}\n"); } else { // Singular field. + char buffer[kFastToBufferSize]; + vars["has_array_index"] = SimpleItoa(field->index() / 32); + vars["has_mask"] = FastHex32ToBuffer(1u << (field->index() % 32), buffer); printer->Print(vars, "inline bool $classname$::has_$name$() const {\n" - " return _has_bit($index$);\n" - "}\n"); + " return (_has_bits_[$has_array_index$] & 0x$has_mask$u) != 0;\n" + "}\n" + "inline void $classname$::set_has_$name$() {\n" + " _has_bits_[$has_array_index$] |= 0x$has_mask$u;\n" + "}\n" + "inline void $classname$::clear_has_$name$() {\n" + " _has_bits_[$has_array_index$] &= ~0x$has_mask$u;\n" + "}\n" + ); } // Generate clear_$name$() @@ -279,7 +421,8 @@ GenerateFieldAccessorDefinitions(io::Printer* printer) { printer->Outdent(); if (!field->is_repeated()) { - printer->Print(vars, " _clear_bit($index$);\n"); + printer->Print(vars, + " clear_has_$name$();\n"); } printer->Print("}\n"); @@ -444,28 +587,74 @@ GenerateClassDefinition(io::Printer* printer) { "// @@protoc_insertion_point(class_scope:$full_name$)\n", "full_name", descriptor_->full_name()); - // Generate private members for fields. + // Generate private members. printer->Outdent(); printer->Print(" private:\n"); printer->Indent(); + for (int i = 0; i < descriptor_->field_count(); i++) { + if (!descriptor_->field(i)->is_repeated()) { + printer->Print( + "inline void set_has_$name$();\n", + "name", FieldName(descriptor_->field(i))); + printer->Print( + "inline void clear_has_$name$();\n", + "name", FieldName(descriptor_->field(i))); + } + } + printer->Print("\n"); + + // To minimize padding, data members are divided into three sections: + // (1) members assumed to align to 8 bytes + // (2) members corresponding to message fields, re-ordered to optimize + // alignment. + // (3) members assumed to align to 4 bytes. + + // Members assumed to align to 8 bytes: + if (descriptor_->extension_range_count() > 0) { printer->Print( - "::google::protobuf::internal::ExtensionSet _extensions_;\n"); + "::google::protobuf::internal::ExtensionSet _extensions_;\n" + "\n"); } if (HasUnknownFields(descriptor_->file())) { printer->Print( - "::google::protobuf::UnknownFieldSet _unknown_fields_;\n"); + "::google::protobuf::UnknownFieldSet _unknown_fields_;\n" + "\n"); + } + + // Field members: + + vector<const FieldDescriptor*> fields; + for (int i = 0; i < descriptor_->field_count(); i++) { + fields.push_back(descriptor_->field(i)); + } + OptimizePadding(&fields); + for (int i = 0; i < fields.size(); ++i) { + field_generators_.get(fields[i]).GeneratePrivateMembers(printer); } + // Members assumed to align to 4 bytes: + // TODO(kenton): Make _cached_size_ an atomic<int> when C++ supports it. printer->Print( - "mutable int _cached_size_;\n" - "\n"); - for (int i = 0; i < descriptor_->field_count(); i++) { - field_generators_.get(descriptor_->field(i)) - .GeneratePrivateMembers(printer); + "\n" + "mutable int _cached_size_;\n"); + + // Generate _has_bits_. + if (descriptor_->field_count() > 0) { + printer->Print(vars, + "::google::protobuf::uint32 _has_bits_[($field_count$ + 31) / 32];\n" + "\n"); + } else { + // Zero-size arrays aren't technically allowed, and MSVC in particular + // doesn't like them. We still need to declare these arrays to make + // other code compile. Since this is an uncommon case, we'll just declare + // them with size 1 and waste some space. Oh well. + printer->Print( + "::google::protobuf::uint32 _has_bits_[1];\n" + "\n"); } // Declare AddDescriptors(), BuildDescriptors(), and ShutdownFile() as @@ -484,32 +673,7 @@ GenerateClassDefinition(io::Printer* printer) { GlobalAssignDescriptorsName(descriptor_->file()->name()), "shutdownfilename", GlobalShutdownFileName(descriptor_->file()->name())); - // Generate offsets and _has_bits_ boilerplate. - if (descriptor_->field_count() > 0) { - printer->Print(vars, - "::google::protobuf::uint32 _has_bits_[($field_count$ + 31) / 32];\n"); - } else { - // Zero-size arrays aren't technically allowed, and MSVC in particular - // doesn't like them. We still need to declare these arrays to make - // other code compile. Since this is an uncommon case, we'll just declare - // them with size 1 and waste some space. Oh well. - printer->Print( - "::google::protobuf::uint32 _has_bits_[1];\n"); - } - printer->Print( - "\n" - "// WHY DOES & HAVE LOWER PRECEDENCE THAN != !?\n" - "inline bool _has_bit(int index) const {\n" - " return (_has_bits_[index / 32] & (1u << (index % 32))) != 0;\n" - "}\n" - "inline void _set_bit(int index) {\n" - " _has_bits_[index / 32] |= (1u << (index % 32));\n" - "}\n" - "inline void _clear_bit(int index) {\n" - " _has_bits_[index / 32] &= ~(1u << (index % 32));\n" - "}\n" - "\n" "void InitAsDefaultInstance();\n" "static $classname$* default_instance_;\n", "classname", classname_); @@ -961,9 +1125,6 @@ GenerateClear(io::Printer* printer) { const FieldDescriptor* field = descriptor_->field(i); if (!field->is_repeated()) { - map<string, string> vars; - vars["index"] = SimpleItoa(field->index()); - // We can use the fact that _has_bits_ is a giant bitfield to our // advantage: We can check up to 32 bits at a time for equality to // zero, and skip the whole range if so. This can improve the speed @@ -975,8 +1136,9 @@ GenerateClear(io::Printer* printer) { printer->Outdent(); printer->Print("}\n"); } - printer->Print(vars, - "if (_has_bits_[$index$ / 32] & (0xffu << ($index$ % 32))) {\n"); + printer->Print( + "if (_has_bits_[$index$ / 32] & (0xffu << ($index$ % 32))) {\n", + "index", SimpleItoa(field->index())); printer->Indent(); } last_index = i; @@ -989,7 +1151,9 @@ GenerateClear(io::Printer* printer) { field->cpp_type() == FieldDescriptor::CPPTYPE_STRING; if (should_check_bit) { - printer->Print(vars, "if (_has_bit($index$)) {\n"); + printer->Print( + "if (has_$name$()) {\n", + "name", FieldName(field)); printer->Indent(); } @@ -1129,24 +1293,23 @@ GenerateMergeFrom(io::Printer* printer) { const FieldDescriptor* field = descriptor_->field(i); if (!field->is_repeated()) { - map<string, string> vars; - vars["index"] = SimpleItoa(field->index()); - // See above in GenerateClear for an explanation of this. if (i / 8 != last_index / 8 || last_index < 0) { if (last_index >= 0) { printer->Outdent(); printer->Print("}\n"); } - printer->Print(vars, - "if (from._has_bits_[$index$ / 32] & (0xffu << ($index$ % 32))) {\n"); + printer->Print( + "if (from._has_bits_[$index$ / 32] & (0xffu << ($index$ % 32))) {\n", + "index", SimpleItoa(field->index())); printer->Indent(); } last_index = i; - printer->Print(vars, - "if (from._has_bit($index$)) {\n"); + printer->Print( + "if (from.has_$name$()) {\n", + "name", FieldName(field)); printer->Indent(); field_generators_.get(field).GenerateMergingCode(printer); @@ -1422,8 +1585,8 @@ void MessageGenerator::GenerateSerializeOneField( if (!field->is_repeated()) { printer->Print( - "if (_has_bit($index$)) {\n", - "index", SimpleItoa(field->index())); + "if (has_$name$()) {\n", + "name", FieldName(field)); printer->Indent(); } diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_message_field.cc b/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_message_field.cc index c04bdc6..23e75b8 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_message_field.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_message_field.cc @@ -75,7 +75,8 @@ void MessageFieldGenerator:: GenerateAccessorDeclarations(io::Printer* printer) const { printer->Print(variables_, "inline const $type$& $name$() const$deprecation$;\n" - "inline $type$* mutable_$name$()$deprecation$;\n"); + "inline $type$* mutable_$name$()$deprecation$;\n" + "inline $type$* release_$name$()$deprecation$;\n"); } void MessageFieldGenerator:: @@ -85,9 +86,15 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { " return $name$_ != NULL ? *$name$_ : *default_instance_->$name$_;\n" "}\n" "inline $type$* $classname$::mutable_$name$() {\n" - " _set_bit($index$);\n" + " set_has_$name$();\n" " if ($name$_ == NULL) $name$_ = new $type$;\n" " return $name$_;\n" + "}\n" + "inline $type$* $classname$::release_$name$() {\n" + " clear_has_$name$();\n" + " $type$* temp = $name$_;\n" + " $name$_ = NULL;\n" + " return temp;\n" "}\n"); } diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc b/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc index 440b716..5c4aa4f 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc @@ -56,24 +56,24 @@ class TestGenerator : public CodeGenerator { virtual bool Generate(const FileDescriptor* file, const string& parameter, - OutputDirectory* output_directory, + GeneratorContext* context, string* error) const { - TryInsert("test.pb.h", "includes", output_directory); - TryInsert("test.pb.h", "namespace_scope", output_directory); - TryInsert("test.pb.h", "global_scope", output_directory); - TryInsert("test.pb.h", "class_scope:foo.Bar", output_directory); - TryInsert("test.pb.h", "class_scope:foo.Bar.Baz", output_directory); + TryInsert("test.pb.h", "includes", context); + TryInsert("test.pb.h", "namespace_scope", context); + TryInsert("test.pb.h", "global_scope", context); + TryInsert("test.pb.h", "class_scope:foo.Bar", context); + TryInsert("test.pb.h", "class_scope:foo.Bar.Baz", context); - TryInsert("test.pb.cc", "includes", output_directory); - TryInsert("test.pb.cc", "namespace_scope", output_directory); - TryInsert("test.pb.cc", "global_scope", output_directory); + TryInsert("test.pb.cc", "includes", context); + TryInsert("test.pb.cc", "namespace_scope", context); + TryInsert("test.pb.cc", "global_scope", context); return true; } void TryInsert(const string& filename, const string& insertion_point, - OutputDirectory* output_directory) const { + GeneratorContext* context) const { scoped_ptr<io::ZeroCopyOutputStream> output( - output_directory->OpenForInsert(filename, insertion_point)); + context->OpenForInsert(filename, insertion_point)); io::Printer printer(output.get(), '$'); printer.Print("// inserted $name$\n", "name", insertion_point); } diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc b/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc index a69c48b..5e8df0f 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc @@ -125,7 +125,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { " return $name$_;\n" "}\n" "inline void $classname$::set_$name$($type$ value) {\n" - " _set_bit($index$);\n" + " set_has_$name$();\n" " $name$_ = value;\n" "}\n"); } @@ -156,7 +156,7 @@ GenerateMergeFromCodedStream(io::Printer* printer) const { "DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n" " $type$, $wire_format_field_type$>(\n" " input, &$name$_)));\n" - "_set_bit($index$);\n"); + "set_has_$name$();\n"); } void PrimitiveFieldGenerator:: diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_string_field.cc b/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_string_field.cc index ea6809a..8d611b6 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_string_field.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_string_field.cc @@ -48,8 +48,10 @@ namespace { void SetStringVariables(const FieldDescriptor* descriptor, map<string, string>* variables) { SetCommonFieldVariables(descriptor, variables); - (*variables)["default"] = - "\"" + CEscape(descriptor->default_value_string()) + "\""; + (*variables)["default"] = DefaultValue(descriptor); + (*variables)["default_variable"] = descriptor->default_value_string().empty() + ? "::google::protobuf::internal::kEmptyString" + : "_default_" + FieldName(descriptor) + "_"; (*variables)["pointer_type"] = descriptor->type() == FieldDescriptor::TYPE_BYTES ? "void" : "char"; } @@ -68,9 +70,10 @@ StringFieldGenerator::~StringFieldGenerator() {} void StringFieldGenerator:: GeneratePrivateMembers(io::Printer* printer) const { - printer->Print(variables_, - "::std::string* $name$_;\n" - "static const ::std::string _default_$name$_;\n"); + printer->Print(variables_, "::std::string* $name$_;\n"); + if (!descriptor_->default_value_string().empty()) { + printer->Print(variables_, "static const ::std::string $default_variable$;\n"); + } } void StringFieldGenerator:: @@ -105,7 +108,8 @@ GenerateAccessorDeclarations(io::Printer* printer) const { "inline void set_$name$(const char* value)$deprecation$;\n" "inline void set_$name$(const $pointer_type$* value, size_t size)" "$deprecation$;\n" - "inline ::std::string* mutable_$name$()$deprecation$;\n"); + "inline ::std::string* mutable_$name$()$deprecation$;\n" + "inline ::std::string* release_$name$()$deprecation$;\n"); if (descriptor_->options().ctype() != FieldOptions::STRING) { printer->Outdent(); @@ -121,51 +125,58 @@ GenerateInlineAccessorDefinitions(io::Printer* printer) const { " return *$name$_;\n" "}\n" "inline void $classname$::set_$name$(const ::std::string& value) {\n" - " _set_bit($index$);\n" - " if ($name$_ == &_default_$name$_) {\n" + " set_has_$name$();\n" + " if ($name$_ == &$default_variable$) {\n" " $name$_ = new ::std::string;\n" " }\n" " $name$_->assign(value);\n" "}\n" "inline void $classname$::set_$name$(const char* value) {\n" - " _set_bit($index$);\n" - " if ($name$_ == &_default_$name$_) {\n" + " set_has_$name$();\n" + " if ($name$_ == &$default_variable$) {\n" " $name$_ = new ::std::string;\n" " }\n" " $name$_->assign(value);\n" "}\n" "inline " "void $classname$::set_$name$(const $pointer_type$* value, size_t size) {\n" - " _set_bit($index$);\n" - " if ($name$_ == &_default_$name$_) {\n" + " set_has_$name$();\n" + " if ($name$_ == &$default_variable$) {\n" " $name$_ = new ::std::string;\n" " }\n" " $name$_->assign(reinterpret_cast<const char*>(value), size);\n" "}\n" "inline ::std::string* $classname$::mutable_$name$() {\n" - " _set_bit($index$);\n" - " if ($name$_ == &_default_$name$_) {\n"); + " set_has_$name$();\n" + " if ($name$_ == &$default_variable$) {\n"); if (descriptor_->default_value_string().empty()) { printer->Print(variables_, " $name$_ = new ::std::string;\n"); } else { printer->Print(variables_, - " $name$_ = new ::std::string(_default_$name$_);\n"); + " $name$_ = new ::std::string($default_variable$);\n"); } printer->Print(variables_, " }\n" " return $name$_;\n" + "}\n" + "inline ::std::string* $classname$::release_$name$() {\n" + " clear_has_$name$();\n" + " if ($name$_ == &$default_variable$) {\n" + " return NULL;\n" + " } else {\n" + " ::std::string* temp = $name$_;\n" + " $name$_ = const_cast< ::std::string*>(&$default_variable$);\n" + " return temp;\n" + " }\n" "}\n"); } void StringFieldGenerator:: GenerateNonInlineAccessorDefinitions(io::Printer* printer) const { - if (descriptor_->default_value_string().empty()) { - printer->Print(variables_, - "const ::std::string $classname$::_default_$name$_;\n"); - } else { + if (!descriptor_->default_value_string().empty()) { printer->Print(variables_, - "const ::std::string $classname$::_default_$name$_($default$);\n"); + "const ::std::string $classname$::$default_variable$($default$);\n"); } } @@ -173,13 +184,13 @@ void StringFieldGenerator:: GenerateClearingCode(io::Printer* printer) const { if (descriptor_->default_value_string().empty()) { printer->Print(variables_, - "if ($name$_ != &_default_$name$_) {\n" + "if ($name$_ != &$default_variable$) {\n" " $name$_->clear();\n" "}\n"); } else { printer->Print(variables_, - "if ($name$_ != &_default_$name$_) {\n" - " $name$_->assign(_default_$name$_);\n" + "if ($name$_ != &$default_variable$) {\n" + " $name$_->assign($default_variable$);\n" "}\n"); } } @@ -197,13 +208,13 @@ GenerateSwappingCode(io::Printer* printer) const { void StringFieldGenerator:: GenerateConstructorCode(io::Printer* printer) const { printer->Print(variables_, - "$name$_ = const_cast< ::std::string*>(&_default_$name$_);\n"); + "$name$_ = const_cast< ::std::string*>(&$default_variable$);\n"); } void StringFieldGenerator:: GenerateDestructorCode(io::Printer* printer) const { printer->Print(variables_, - "if ($name$_ != &_default_$name$_) {\n" + "if ($name$_ != &$default_variable$) {\n" " delete $name$_;\n" "}\n"); } diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto b/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto index 79971a9..54d830f 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto +++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto @@ -36,6 +36,10 @@ // though the same identifiers are used internally by the C++ code generator. +// Some generic_services option(s) added automatically. +// See: http://go/proto2-generic-services-default +option cc_generic_services = true; // auto-added + // We don't put this in a package within proto2 because we need to make sure // that the generated code doesn't depend on being in the proto2 namespace. package protobuf_unittest; diff --git a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_unittest.cc b/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_unittest.cc index a7e852d..301a7ce 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_unittest.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/cpp/cpp_unittest.cc @@ -167,6 +167,13 @@ TEST(GeneratedMessageTest, FloatingPointDefaults) { EXPECT_TRUE(extreme_default.nan_float() != extreme_default.nan_float()); } +TEST(GeneratedMessageTest, Trigraph) { + const unittest::TestExtremeDefaultValues& extreme_default = + unittest::TestExtremeDefaultValues::default_instance(); + + EXPECT_EQ("? ? ?? ?? ??? ?\?/ ?\?-", extreme_default.cpp_trigraph()); +} + TEST(GeneratedMessageTest, Accessors) { // Set every field to a unique value then go back and check all those // values. @@ -195,6 +202,48 @@ TEST(GeneratedMessageTest, MutableStringDefault) { EXPECT_EQ("hello", *message.mutable_default_string()); } +TEST(GeneratedMessageTest, ReleaseString) { + // Check that release_foo() starts out NULL, and gives us a value + // that we can delete after it's been set. + unittest::TestAllTypes message; + + EXPECT_EQ(NULL, message.release_default_string()); + EXPECT_FALSE(message.has_default_string()); + EXPECT_EQ("hello", message.default_string()); + + message.set_default_string("blah"); + EXPECT_TRUE(message.has_default_string()); + string* str = message.release_default_string(); + EXPECT_FALSE(message.has_default_string()); + ASSERT_TRUE(str != NULL); + EXPECT_EQ("blah", *str); + delete str; + + EXPECT_EQ(NULL, message.release_default_string()); + EXPECT_FALSE(message.has_default_string()); + EXPECT_EQ("hello", message.default_string()); +} + +TEST(GeneratedMessageTest, ReleaseMessage) { + // Check that release_foo() starts out NULL, and gives us a value + // that we can delete after it's been set. + unittest::TestAllTypes message; + + EXPECT_EQ(NULL, message.release_optional_nested_message()); + EXPECT_FALSE(message.has_optional_nested_message()); + + message.mutable_optional_nested_message()->set_bb(1); + unittest::TestAllTypes::NestedMessage* nest = + message.release_optional_nested_message(); + EXPECT_FALSE(message.has_optional_nested_message()); + ASSERT_TRUE(nest != NULL); + EXPECT_EQ(1, nest->bb()); + delete nest; + + EXPECT_EQ(NULL, message.release_optional_nested_message()); + EXPECT_FALSE(message.has_optional_nested_message()); +} + TEST(GeneratedMessageTest, Clear) { // Set every field to a unique value, clear the message, then check that // it is cleared. @@ -282,6 +331,7 @@ TEST(GeneratedMessageTest, CopyFrom) { TestUtil::ExpectAllFieldsSet(message2); } + TEST(GeneratedMessageTest, SwapWithEmpty) { unittest::TestAllTypes message1, message2; TestUtil::SetAllFields(&message1); @@ -376,7 +426,7 @@ TEST(GeneratedMessageTest, CopyAssignmentOperator) { TestUtil::ExpectAllFieldsSet(message2); // Make sure that self-assignment does something sane. - message2 = message2; + message2.operator=(message2); TestUtil::ExpectAllFieldsSet(message2); } @@ -718,6 +768,7 @@ TEST(GeneratedMessageTest, TestSpaceUsed) { #endif // !PROTOBUF_TEST_NO_DESCRIPTORS + TEST(GeneratedMessageTest, FieldConstantValues) { unittest::TestRequired message; EXPECT_EQ(unittest::TestAllTypes_NestedMessage::kBbFieldNumber, 1); @@ -809,14 +860,14 @@ TEST(GeneratedEnumTest, MinAndMax) { EXPECT_EQ(12589235, unittest::TestSparseEnum_ARRAYSIZE); // Make sure we can take the address of _MIN, _MAX and _ARRAYSIZE. - void* nullptr = 0; // NULL may be integer-type, not pointer-type. - EXPECT_NE(nullptr, &unittest::TestAllTypes::NestedEnum_MIN); - EXPECT_NE(nullptr, &unittest::TestAllTypes::NestedEnum_MAX); - EXPECT_NE(nullptr, &unittest::TestAllTypes::NestedEnum_ARRAYSIZE); - - EXPECT_NE(nullptr, &unittest::ForeignEnum_MIN); - EXPECT_NE(nullptr, &unittest::ForeignEnum_MAX); - EXPECT_NE(nullptr, &unittest::ForeignEnum_ARRAYSIZE); + void* null_pointer = 0; // NULL may be integer-type, not pointer-type. + EXPECT_NE(null_pointer, &unittest::TestAllTypes::NestedEnum_MIN); + EXPECT_NE(null_pointer, &unittest::TestAllTypes::NestedEnum_MAX); + EXPECT_NE(null_pointer, &unittest::TestAllTypes::NestedEnum_ARRAYSIZE); + + EXPECT_NE(null_pointer, &unittest::ForeignEnum_MIN); + EXPECT_NE(null_pointer, &unittest::ForeignEnum_MAX); + EXPECT_NE(null_pointer, &unittest::ForeignEnum_ARRAYSIZE); // Make sure we can use _MIN, _MAX and _ARRAYSIZE as switch cases. switch (unittest::SPARSE_A) { diff --git a/third_party/protobuf/src/google/protobuf/compiler/importer.cc b/third_party/protobuf/src/google/protobuf/compiler/importer.cc index 7689ce9..422f759 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/importer.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/importer.cc @@ -231,7 +231,12 @@ static string CanonicalizePath(string path) { // The Win32 API accepts forward slashes as a path delimiter even though // backslashes are standard. Let's avoid confusion and use only forward // slashes. - path = StringReplace(path, "\\", "/", true); + if (HasPrefixString(path, "\\\\")) { + // Avoid converting two leading backslashes. + path = "\\\\" + StringReplace(path.substr(2), "\\", "/", true); + } else { + path = StringReplace(path, "\\", "/", true); + } #endif vector<string> parts; diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_enum.cc b/third_party/protobuf/src/google/protobuf/compiler/java/java_enum.cc index e796587..9d7bcab 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_enum.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/java/java_enum.cc @@ -104,6 +104,15 @@ void EnumGenerator::Generate(io::Printer* printer) { "public static final $classname$ $name$ = $canonical_name$;\n"); } + for (int i = 0; i < descriptor_->value_count(); i++) { + map<string, string> vars; + vars["name"] = descriptor_->value(i)->name(); + vars["number"] = SimpleItoa(descriptor_->value(i)->number()); + printer->Print(vars, + "public static final int $name$_VALUE = $number$;\n"); + } + printer->Print("\n"); + // ----------------------------------------------------------------- printer->Print( @@ -219,17 +228,6 @@ void EnumGenerator::Generate(io::Printer* printer) { " this.value = value;\n" "}\n"); - if (HasDescriptorMethods(descriptor_)) { - // Force the static initialization code for the file to run, since it may - // initialize static variables declared in this class. - printer->Print( - "\n" - "static {\n" - " $file$.getDescriptor();\n" - "}\n", - "file", ClassName(descriptor_->file())); - } - printer->Print( "\n" "// @@protoc_insertion_point(enum_scope:$full_name$)\n", diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_enum_field.cc b/third_party/protobuf/src/google/protobuf/compiler/java/java_enum_field.cc index af6b1cd..72caa10 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_enum_field.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/java/java_enum_field.cc @@ -52,17 +52,44 @@ namespace { // TODO(kenton): Factor out a "SetCommonFieldVariables()" to get rid of // repeat code between this and the other field types. void SetEnumVariables(const FieldDescriptor* descriptor, + int messageBitIndex, + int builderBitIndex, map<string, string>* variables) { (*variables)["name"] = UnderscoresToCamelCase(descriptor); (*variables)["capitalized_name"] = UnderscoresToCapitalizedCamelCase(descriptor); + (*variables)["constant_name"] = FieldConstantName(descriptor); (*variables)["number"] = SimpleItoa(descriptor->number()); (*variables)["type"] = ClassName(descriptor->enum_type()); (*variables)["default"] = DefaultValue(descriptor); (*variables)["tag"] = SimpleItoa(internal::WireFormat::MakeTag(descriptor)); (*variables)["tag_size"] = SimpleItoa( internal::WireFormat::TagSize(descriptor->number(), GetType(descriptor))); + // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported + // by the proto compiler + (*variables)["deprecation"] = descriptor->options().deprecated() + ? "@java.lang.Deprecated " : ""; + (*variables)["on_changed"] = + HasDescriptorMethods(descriptor->containing_type()) ? "onChanged();" : ""; + + // For singular messages and builders, one bit is used for the hasField bit. + (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex); + + (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex); + (*variables)["set_has_field_bit_builder"] = GenerateSetBit(builderBitIndex); + (*variables)["clear_has_field_bit_builder"] = + GenerateClearBit(builderBitIndex); + + // For repated builders, one bit is used for whether the array is immutable. + (*variables)["get_mutable_bit_builder"] = GenerateGetBit(builderBitIndex); + (*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex); + (*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex); + + (*variables)["get_has_field_bit_from_local"] = + GenerateGetBitFromLocal(builderBitIndex); + (*variables)["set_has_field_bit_to_local"] = + GenerateSetBitToLocal(messageBitIndex); } } // namespace @@ -70,52 +97,88 @@ void SetEnumVariables(const FieldDescriptor* descriptor, // =================================================================== EnumFieldGenerator:: -EnumFieldGenerator(const FieldDescriptor* descriptor) - : descriptor_(descriptor) { - SetEnumVariables(descriptor, &variables_); +EnumFieldGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, + int builderBitIndex) + : descriptor_(descriptor), messageBitIndex_(messageBitIndex), + builderBitIndex_(builderBitIndex) { + SetEnumVariables(descriptor, messageBitIndex, builderBitIndex, &variables_); } EnumFieldGenerator::~EnumFieldGenerator() {} +int EnumFieldGenerator::GetNumBitsForMessage() const { + return 1; +} + +int EnumFieldGenerator::GetNumBitsForBuilder() const { + return 1; +} + +void EnumFieldGenerator:: +GenerateInterfaceMembers(io::Printer* printer) const { + printer->Print(variables_, + "$deprecation$boolean has$capitalized_name$();\n" + "$deprecation$$type$ get$capitalized_name$();\n"); +} + void EnumFieldGenerator:: GenerateMembers(io::Printer* printer) const { printer->Print(variables_, - "private boolean has$capitalized_name$;\n" "private $type$ $name$_;\n" - "public boolean has$capitalized_name$() { return has$capitalized_name$; }\n" - "public $type$ get$capitalized_name$() { return $name$_; }\n"); + "$deprecation$public boolean has$capitalized_name$() {\n" + " return $get_has_field_bit_message$;\n" + "}\n" + "$deprecation$public $type$ get$capitalized_name$() {\n" + " return $name$_;\n" + "}\n"); } void EnumFieldGenerator:: GenerateBuilderMembers(io::Printer* printer) const { printer->Print(variables_, - "public boolean has$capitalized_name$() {\n" - " return result.has$capitalized_name$();\n" + "private $type$ $name$_ = $default$;\n" + "$deprecation$public boolean has$capitalized_name$() {\n" + " return $get_has_field_bit_builder$;\n" "}\n" - "public $type$ get$capitalized_name$() {\n" - " return result.get$capitalized_name$();\n" + "$deprecation$public $type$ get$capitalized_name$() {\n" + " return $name$_;\n" "}\n" - "public Builder set$capitalized_name$($type$ value) {\n" + "$deprecation$public Builder set$capitalized_name$($type$ value) {\n" " if (value == null) {\n" " throw new NullPointerException();\n" " }\n" - " result.has$capitalized_name$ = true;\n" - " result.$name$_ = value;\n" + " $set_has_field_bit_builder$;\n" + " $name$_ = value;\n" + " $on_changed$\n" " return this;\n" "}\n" - "public Builder clear$capitalized_name$() {\n" - " result.has$capitalized_name$ = false;\n" - " result.$name$_ = $default$;\n" + "$deprecation$public Builder clear$capitalized_name$() {\n" + " $clear_has_field_bit_builder$;\n" + " $name$_ = $default$;\n" + " $on_changed$\n" " return this;\n" "}\n"); } void EnumFieldGenerator:: +GenerateFieldBuilderInitializationCode(io::Printer* printer) const { + // noop for enums +} + +void EnumFieldGenerator:: GenerateInitializationCode(io::Printer* printer) const { printer->Print(variables_, "$name$_ = $default$;\n"); } void EnumFieldGenerator:: +GenerateBuilderClearCode(io::Printer* printer) const { + printer->Print(variables_, + "$name$_ = $default$;\n" + "$clear_has_field_bit_builder$;\n"); +} + +void EnumFieldGenerator:: GenerateMergingCode(io::Printer* printer) const { printer->Print(variables_, "if (other.has$capitalized_name$()) {\n" @@ -125,7 +188,11 @@ GenerateMergingCode(io::Printer* printer) const { void EnumFieldGenerator:: GenerateBuildingCode(io::Printer* printer) const { - // Nothing to do here for enum types. + printer->Print(variables_, + "if ($get_has_field_bit_from_local$) {\n" + " $set_has_field_bit_to_local$;\n" + "}\n" + "result.$name$_ = $name$_;\n"); } void EnumFieldGenerator:: @@ -143,27 +210,42 @@ GenerateParsingCode(io::Printer* printer) const { "if (value != null) {\n"); } printer->Print(variables_, - " set$capitalized_name$(value);\n" + " $set_has_field_bit_builder$;\n" + " $name$_ = value;\n" "}\n"); } void EnumFieldGenerator:: GenerateSerializationCode(io::Printer* printer) const { printer->Print(variables_, - "if (has$capitalized_name$()) {\n" - " output.writeEnum($number$, get$capitalized_name$().getNumber());\n" + "if ($get_has_field_bit_message$) {\n" + " output.writeEnum($number$, $name$_.getNumber());\n" "}\n"); } void EnumFieldGenerator:: GenerateSerializedSizeCode(io::Printer* printer) const { printer->Print(variables_, - "if (has$capitalized_name$()) {\n" + "if ($get_has_field_bit_message$) {\n" " size += com.google.protobuf.CodedOutputStream\n" - " .computeEnumSize($number$, get$capitalized_name$().getNumber());\n" + " .computeEnumSize($number$, $name$_.getNumber());\n" "}\n"); } +void EnumFieldGenerator:: +GenerateEqualsCode(io::Printer* printer) const { + printer->Print(variables_, + "result = result &&\n" + " (get$capitalized_name$() == other.get$capitalized_name$());\n"); +} + +void EnumFieldGenerator:: +GenerateHashCode(io::Printer* printer) const { + printer->Print(variables_, + "hash = (37 * hash) + $constant_name$;\n" + "hash = (53 * hash) + hashEnum(get$capitalized_name$());\n"); +} + string EnumFieldGenerator::GetBoxedType() const { return ClassName(descriptor_->enum_type()); } @@ -171,23 +253,43 @@ string EnumFieldGenerator::GetBoxedType() const { // =================================================================== RepeatedEnumFieldGenerator:: -RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor) - : descriptor_(descriptor) { - SetEnumVariables(descriptor, &variables_); +RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, + int builderBitIndex) + : descriptor_(descriptor), messageBitIndex_(messageBitIndex), + builderBitIndex_(builderBitIndex) { + SetEnumVariables(descriptor, messageBitIndex, builderBitIndex, &variables_); } RepeatedEnumFieldGenerator::~RepeatedEnumFieldGenerator() {} +int RepeatedEnumFieldGenerator::GetNumBitsForMessage() const { + return 0; +} + +int RepeatedEnumFieldGenerator::GetNumBitsForBuilder() const { + return 1; +} + +void RepeatedEnumFieldGenerator:: +GenerateInterfaceMembers(io::Printer* printer) const { + printer->Print(variables_, + "$deprecation$java.util.List<$type$> get$capitalized_name$List();\n" + "$deprecation$int get$capitalized_name$Count();\n" + "$deprecation$$type$ get$capitalized_name$(int index);\n"); +} + void RepeatedEnumFieldGenerator:: GenerateMembers(io::Printer* printer) const { printer->Print(variables_, - "private java.util.List<$type$> $name$_ =\n" - " java.util.Collections.emptyList();\n" - "public java.util.List<$type$> get$capitalized_name$List() {\n" + "private java.util.List<$type$> $name$_;\n" + "$deprecation$public java.util.List<$type$> get$capitalized_name$List() {\n" " return $name$_;\n" // note: unmodifiable list "}\n" - "public int get$capitalized_name$Count() { return $name$_.size(); }\n" - "public $type$ get$capitalized_name$(int index) {\n" + "$deprecation$public int get$capitalized_name$Count() {\n" + " return $name$_.size();\n" + "}\n" + "$deprecation$public $type$ get$capitalized_name$(int index) {\n" " return $name$_.get(index);\n" "}\n"); @@ -201,73 +303,119 @@ GenerateMembers(io::Printer* printer) const { void RepeatedEnumFieldGenerator:: GenerateBuilderMembers(io::Printer* printer) const { printer->Print(variables_, + // One field is the list and the other field keeps track of whether the + // list is immutable. If it's immutable, the invariant is that it must + // either an instance of Collections.emptyList() or it's an ArrayList + // wrapped in a Collections.unmodifiableList() wrapper and nobody else has + // a refererence to the underlying ArrayList. This invariant allows us to + // share instances of lists between protocol buffers avoiding expensive + // memory allocations. Note, immutable is a strong guarantee here -- not + // just that the list cannot be modified via the reference but that the + // list can never be modified. + "private java.util.List<$type$> $name$_ =\n" + " java.util.Collections.emptyList();\n" + + "private void ensure$capitalized_name$IsMutable() {\n" + " if (!$get_mutable_bit_builder$) {\n" + " $name$_ = new java.util.ArrayList<$type$>($name$_);\n" + " $set_mutable_bit_builder$;\n" + " }\n" + "}\n" + // Note: We return an unmodifiable list because otherwise the caller // could hold on to the returned list and modify it after the message // has been built, thus mutating the message which is supposed to be // immutable. - "public java.util.List<$type$> get$capitalized_name$List() {\n" - " return java.util.Collections.unmodifiableList(result.$name$_);\n" + "$deprecation$public java.util.List<$type$> get$capitalized_name$List() {\n" + " return java.util.Collections.unmodifiableList($name$_);\n" "}\n" - "public int get$capitalized_name$Count() {\n" - " return result.get$capitalized_name$Count();\n" + "$deprecation$public int get$capitalized_name$Count() {\n" + " return $name$_.size();\n" "}\n" - "public $type$ get$capitalized_name$(int index) {\n" - " return result.get$capitalized_name$(index);\n" + "$deprecation$public $type$ get$capitalized_name$(int index) {\n" + " return $name$_.get(index);\n" "}\n" - "public Builder set$capitalized_name$(int index, $type$ value) {\n" + "$deprecation$public Builder set$capitalized_name$(\n" + " int index, $type$ value) {\n" " if (value == null) {\n" " throw new NullPointerException();\n" " }\n" - " result.$name$_.set(index, value);\n" + " ensure$capitalized_name$IsMutable();\n" + " $name$_.set(index, value);\n" + " $on_changed$\n" " return this;\n" "}\n" - "public Builder add$capitalized_name$($type$ value) {\n" + "$deprecation$public Builder add$capitalized_name$($type$ value) {\n" " if (value == null) {\n" " throw new NullPointerException();\n" " }\n" - " if (result.$name$_.isEmpty()) {\n" - " result.$name$_ = new java.util.ArrayList<$type$>();\n" - " }\n" - " result.$name$_.add(value);\n" + " ensure$capitalized_name$IsMutable();\n" + " $name$_.add(value);\n" + " $on_changed$\n" " return this;\n" "}\n" - "public Builder addAll$capitalized_name$(\n" + "$deprecation$public Builder addAll$capitalized_name$(\n" " java.lang.Iterable<? extends $type$> values) {\n" - " if (result.$name$_.isEmpty()) {\n" - " result.$name$_ = new java.util.ArrayList<$type$>();\n" - " }\n" - " super.addAll(values, result.$name$_);\n" + " ensure$capitalized_name$IsMutable();\n" + " super.addAll(values, $name$_);\n" + " $on_changed$\n" " return this;\n" "}\n" - "public Builder clear$capitalized_name$() {\n" - " result.$name$_ = java.util.Collections.emptyList();\n" + "$deprecation$public Builder clear$capitalized_name$() {\n" + " $name$_ = java.util.Collections.emptyList();\n" + " $clear_mutable_bit_builder$;\n" + " $on_changed$\n" " return this;\n" "}\n"); } void RepeatedEnumFieldGenerator:: +GenerateFieldBuilderInitializationCode(io::Printer* printer) const { + // noop for enums +} + +void RepeatedEnumFieldGenerator:: GenerateInitializationCode(io::Printer* printer) const { - // Initialized inline. + printer->Print(variables_, "$name$_ = java.util.Collections.emptyList();\n"); +} + +void RepeatedEnumFieldGenerator:: +GenerateBuilderClearCode(io::Printer* printer) const { + printer->Print(variables_, + "$name$_ = java.util.Collections.emptyList();\n" + "$clear_mutable_bit_builder$;\n"); } void RepeatedEnumFieldGenerator:: GenerateMergingCode(io::Printer* printer) const { + // The code below does two optimizations: + // 1. If the other list is empty, there's nothing to do. This ensures we + // don't allocate a new array if we already have an immutable one. + // 2. If the other list is non-empty and our current list is empty, we can + // reuse the other list which is guaranteed to be immutable. printer->Print(variables_, "if (!other.$name$_.isEmpty()) {\n" - " if (result.$name$_.isEmpty()) {\n" - " result.$name$_ = new java.util.ArrayList<$type$>();\n" + " if ($name$_.isEmpty()) {\n" + " $name$_ = other.$name$_;\n" + " $clear_mutable_bit_builder$;\n" + " } else {\n" + " ensure$capitalized_name$IsMutable();\n" + " $name$_.addAll(other.$name$_);\n" " }\n" - " result.$name$_.addAll(other.$name$_);\n" + " $on_changed$\n" "}\n"); } void RepeatedEnumFieldGenerator:: GenerateBuildingCode(io::Printer* printer) const { + // The code below ensures that the result has an immutable list. If our + // list is immutable, we can just reuse it. If not, we make it immutable. printer->Print(variables_, - "if (result.$name$_ != java.util.Collections.EMPTY_LIST) {\n" - " result.$name$_ =\n" - " java.util.Collections.unmodifiableList(result.$name$_);\n" - "}\n"); + "if ($get_mutable_bit_builder$) {\n" + " $name$_ = java.util.Collections.unmodifiableList($name$_);\n" + " $clear_mutable_bit_builder$;\n" + "}\n" + "result.$name$_ = $name$_;\n"); } void RepeatedEnumFieldGenerator:: @@ -316,13 +464,13 @@ GenerateSerializationCode(io::Printer* printer) const { " output.writeRawVarint32($tag$);\n" " output.writeRawVarint32($name$MemoizedSerializedSize);\n" "}\n" - "for ($type$ element : get$capitalized_name$List()) {\n" - " output.writeEnumNoTag(element.getNumber());\n" + "for (int i = 0; i < $name$_.size(); i++) {\n" + " output.writeEnumNoTag($name$_.get(i).getNumber());\n" "}\n"); } else { printer->Print(variables_, - "for ($type$ element : get$capitalized_name$List()) {\n" - " output.writeEnum($number$, element.getNumber());\n" + "for (int i = 0; i < $name$_.size(); i++) {\n" + " output.writeEnum($number$, $name$_.get(i).getNumber());\n" "}\n"); } } @@ -335,9 +483,9 @@ GenerateSerializedSizeCode(io::Printer* printer) const { printer->Indent(); printer->Print(variables_, - "for ($type$ element : get$capitalized_name$List()) {\n" + "for (int i = 0; i < $name$_.size(); i++) {\n" " dataSize += com.google.protobuf.CodedOutputStream\n" - " .computeEnumSizeNoTag(element.getNumber());\n" + " .computeEnumSizeNoTag($name$_.get(i).getNumber());\n" "}\n"); printer->Print( "size += dataSize;\n"); @@ -350,7 +498,7 @@ GenerateSerializedSizeCode(io::Printer* printer) const { "}"); } else { printer->Print(variables_, - "size += $tag_size$ * get$capitalized_name$List().size();\n"); + "size += $tag_size$ * $name$_.size();\n"); } // cache the data size for packed fields. @@ -363,6 +511,22 @@ GenerateSerializedSizeCode(io::Printer* printer) const { printer->Print("}\n"); } +void RepeatedEnumFieldGenerator:: +GenerateEqualsCode(io::Printer* printer) const { + printer->Print(variables_, + "result = result && get$capitalized_name$List()\n" + " .equals(other.get$capitalized_name$List());\n"); +} + +void RepeatedEnumFieldGenerator:: +GenerateHashCode(io::Printer* printer) const { + printer->Print(variables_, + "if (get$capitalized_name$Count() > 0) {\n" + " hash = (37 * hash) + $constant_name$;\n" + " hash = (53 * hash) + hashEnumList(get$capitalized_name$List());\n" + "}\n"); +} + string RepeatedEnumFieldGenerator::GetBoxedType() const { return ClassName(descriptor_->enum_type()); } diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_enum_field.h b/third_party/protobuf/src/google/protobuf/compiler/java/java_enum_field.h index c54a0fa..0cad6be 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_enum_field.h +++ b/third_party/protobuf/src/google/protobuf/compiler/java/java_enum_field.h @@ -46,49 +46,69 @@ namespace java { class EnumFieldGenerator : public FieldGenerator { public: - explicit EnumFieldGenerator(const FieldDescriptor* descriptor); + explicit EnumFieldGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, int builderBitIndex); ~EnumFieldGenerator(); // implements FieldGenerator --------------------------------------- + int GetNumBitsForMessage() const; + int GetNumBitsForBuilder() const; + void GenerateInterfaceMembers(io::Printer* printer) const; void GenerateMembers(io::Printer* printer) const; void GenerateBuilderMembers(io::Printer* printer) const; void GenerateInitializationCode(io::Printer* printer) const; + void GenerateBuilderClearCode(io::Printer* printer) const; void GenerateMergingCode(io::Printer* printer) const; void GenerateBuildingCode(io::Printer* printer) const; void GenerateParsingCode(io::Printer* printer) const; void GenerateSerializationCode(io::Printer* printer) const; void GenerateSerializedSizeCode(io::Printer* printer) const; + void GenerateFieldBuilderInitializationCode(io::Printer* printer) const; + void GenerateEqualsCode(io::Printer* printer) const; + void GenerateHashCode(io::Printer* printer) const; string GetBoxedType() const; private: const FieldDescriptor* descriptor_; map<string, string> variables_; + const int messageBitIndex_; + const int builderBitIndex_; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumFieldGenerator); }; class RepeatedEnumFieldGenerator : public FieldGenerator { public: - explicit RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor); + explicit RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, int builderBitIndex); ~RepeatedEnumFieldGenerator(); // implements FieldGenerator --------------------------------------- + int GetNumBitsForMessage() const; + int GetNumBitsForBuilder() const; + void GenerateInterfaceMembers(io::Printer* printer) const; void GenerateMembers(io::Printer* printer) const; void GenerateBuilderMembers(io::Printer* printer) const; void GenerateInitializationCode(io::Printer* printer) const; + void GenerateBuilderClearCode(io::Printer* printer) const; void GenerateMergingCode(io::Printer* printer) const; void GenerateBuildingCode(io::Printer* printer) const; void GenerateParsingCode(io::Printer* printer) const; void GenerateParsingCodeFromPacked(io::Printer* printer) const; void GenerateSerializationCode(io::Printer* printer) const; void GenerateSerializedSizeCode(io::Printer* printer) const; + void GenerateFieldBuilderInitializationCode(io::Printer* printer) const; + void GenerateEqualsCode(io::Printer* printer) const; + void GenerateHashCode(io::Printer* printer) const; string GetBoxedType() const; private: const FieldDescriptor* descriptor_; map<string, string> variables_; + const int messageBitIndex_; + const int builderBitIndex_; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedEnumFieldGenerator); }; diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_extension.cc b/third_party/protobuf/src/google/protobuf/compiler/java/java_extension.cc index 903b0a9..9b147c7 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_extension.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/java/java_extension.cc @@ -86,108 +86,123 @@ ExtensionGenerator::ExtensionGenerator(const FieldDescriptor* descriptor) ExtensionGenerator::~ExtensionGenerator() {} -void ExtensionGenerator::Generate(io::Printer* printer) { - map<string, string> vars; - vars["name"] = UnderscoresToCamelCase(descriptor_); - vars["containing_type"] = ClassName(descriptor_->containing_type()); - vars["number"] = SimpleItoa(descriptor_->number()); - vars["constant_name"] = FieldConstantName(descriptor_); - vars["lite"] = HasDescriptorMethods(descriptor_->file()) ? "" : "Lite"; +// Initializes the vars referenced in the generated code templates. +void InitTemplateVars(const FieldDescriptor* descriptor, + const string& scope, + map<string, string>* vars_pointer) { + map<string, string> &vars = *vars_pointer; + vars["scope"] = scope; + vars["name"] = UnderscoresToCamelCase(descriptor); + vars["containing_type"] = ClassName(descriptor->containing_type()); + vars["number"] = SimpleItoa(descriptor->number()); + vars["constant_name"] = FieldConstantName(descriptor); + vars["index"] = SimpleItoa(descriptor->index()); + vars["default"] = + descriptor->is_repeated() ? "" : DefaultValue(descriptor); + vars["type_constant"] = TypeName(GetType(descriptor)); + vars["packed"] = descriptor->options().packed() ? "true" : "false"; + vars["enum_map"] = "null"; + vars["prototype"] = "null"; - JavaType java_type = GetJavaType(descriptor_); + JavaType java_type = GetJavaType(descriptor); string singular_type; switch (java_type) { case JAVATYPE_MESSAGE: - vars["type"] = ClassName(descriptor_->message_type()); + singular_type = ClassName(descriptor->message_type()); + vars["prototype"] = singular_type + ".getDefaultInstance()"; break; case JAVATYPE_ENUM: - vars["type"] = ClassName(descriptor_->enum_type()); + singular_type = ClassName(descriptor->enum_type()); + vars["enum_map"] = singular_type + ".internalGetValueMap()"; break; default: - vars["type"] = BoxedPrimitiveTypeName(java_type); + singular_type = BoxedPrimitiveTypeName(java_type); break; } - - printer->Print(vars, - "public static final int $constant_name$ = $number$;\n"); - if (descriptor_->is_repeated()) { - printer->Print(vars, - "public static final\n" - " com.google.protobuf.GeneratedMessage$lite$.GeneratedExtension<\n" - " $containing_type$,\n" - " java.util.List<$type$>> $name$ =\n" - " com.google.protobuf.GeneratedMessage$lite$\n" - " .newGeneratedExtension();\n"); - } else { - printer->Print(vars, - "public static final\n" - " com.google.protobuf.GeneratedMessage$lite$.GeneratedExtension<\n" - " $containing_type$,\n" - " $type$> $name$ =\n" - " com.google.protobuf.GeneratedMessage$lite$\n" - " .newGeneratedExtension();\n"); - } + vars["type"] = descriptor->is_repeated() ? + "java.util.List<" + singular_type + ">" : singular_type; + vars["singular_type"] = singular_type; } -void ExtensionGenerator::GenerateInitializationCode(io::Printer* printer) { +void ExtensionGenerator::Generate(io::Printer* printer) { map<string, string> vars; - vars["name"] = UnderscoresToCamelCase(descriptor_); - vars["scope"] = scope_; - vars["index"] = SimpleItoa(descriptor_->index()); - vars["extendee"] = ClassName(descriptor_->containing_type()); - vars["default"] = descriptor_->is_repeated() ? "" : DefaultValue(descriptor_); - vars["number"] = SimpleItoa(descriptor_->number()); - vars["type_constant"] = TypeName(GetType(descriptor_)); - vars["packed"] = descriptor_->options().packed() ? "true" : "false"; - vars["enum_map"] = "null"; - vars["prototype"] = "null"; - - JavaType java_type = GetJavaType(descriptor_); - string singular_type; - switch (java_type) { - case JAVATYPE_MESSAGE: - vars["type"] = ClassName(descriptor_->message_type()); - vars["prototype"] = ClassName(descriptor_->message_type()) + - ".getDefaultInstance()"; - break; - case JAVATYPE_ENUM: - vars["type"] = ClassName(descriptor_->enum_type()); - vars["enum_map"] = ClassName(descriptor_->enum_type()) + - ".internalGetValueMap()"; - break; - default: - vars["type"] = BoxedPrimitiveTypeName(java_type); - break; - } + InitTemplateVars(descriptor_, scope_, &vars); + printer->Print(vars, + "public static final int $constant_name$ = $number$;\n"); if (HasDescriptorMethods(descriptor_->file())) { - printer->Print(vars, - "$scope$.$name$.internalInit(\n" - " $scope$.getDescriptor().getExtensions().get($index$),\n" - " $type$.class);\n"); + // Non-lite extensions + if (descriptor_->extension_scope() == NULL) { + // Non-nested + printer->Print( + vars, + "public static final\n" + " com.google.protobuf.GeneratedMessage.GeneratedExtension<\n" + " $containing_type$,\n" + " $type$> $name$ = com.google.protobuf.GeneratedMessage\n" + " .newFileScopedGeneratedExtension(\n" + " $singular_type$.class,\n" + " $prototype$);\n"); + } else { + // Nested + printer->Print( + vars, + "public static final\n" + " com.google.protobuf.GeneratedMessage.GeneratedExtension<\n" + " $containing_type$,\n" + " $type$> $name$ = com.google.protobuf.GeneratedMessage\n" + " .newMessageScopedGeneratedExtension(\n" + " $scope$.getDefaultInstance(),\n" + " $index$,\n" + " $singular_type$.class,\n" + " $prototype$);\n"); + } } else { + // Lite extensions if (descriptor_->is_repeated()) { - printer->Print(vars, - "$scope$.$name$.internalInitRepeated(\n" - " $extendee$.getDefaultInstance(),\n" - " $prototype$,\n" - " $enum_map$,\n" - " $number$,\n" - " com.google.protobuf.WireFormat.FieldType.$type_constant$,\n" - " $packed$);\n"); + printer->Print( + vars, + "public static final\n" + " com.google.protobuf.GeneratedMessageLite.GeneratedExtension<\n" + " $containing_type$,\n" + " $type$> $name$ = com.google.protobuf.GeneratedMessageLite\n" + " .newRepeatedGeneratedExtension(\n" + " $containing_type$.getDefaultInstance(),\n" + " $prototype$,\n" + " $enum_map$,\n" + " $number$,\n" + " com.google.protobuf.WireFormat.FieldType.$type_constant$,\n" + " $packed$);\n"); } else { - printer->Print(vars, - "$scope$.$name$.internalInitSingular(\n" - " $extendee$.getDefaultInstance(),\n" - " $default$,\n" - " $prototype$,\n" - " $enum_map$,\n" - " $number$,\n" - " com.google.protobuf.WireFormat.FieldType.$type_constant$);\n"); + printer->Print( + vars, + "public static final\n" + " com.google.protobuf.GeneratedMessageLite.GeneratedExtension<\n" + " $containing_type$,\n" + " $type$> $name$ = com.google.protobuf.GeneratedMessageLite\n" + " .newSingularGeneratedExtension(\n" + " $containing_type$.getDefaultInstance(),\n" + " $default$,\n" + " $prototype$,\n" + " $enum_map$,\n" + " $number$,\n" + " com.google.protobuf.WireFormat.FieldType.$type_constant$);\n"); } } } +void ExtensionGenerator::GenerateNonNestedInitializationCode( + io::Printer* printer) { + if (descriptor_->extension_scope() == NULL && + HasDescriptorMethods(descriptor_->file())) { + // Only applies to non-nested, non-lite extensions. + printer->Print( + "$name$.internalInit(descriptor.getExtensions().get($index$));\n", + "name", UnderscoresToCamelCase(descriptor_), + "index", SimpleItoa(descriptor_->index())); + } +} + void ExtensionGenerator::GenerateRegistrationCode(io::Printer* printer) { printer->Print( "registry.add($scope$.$name$);\n", diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_extension.h b/third_party/protobuf/src/google/protobuf/compiler/java/java_extension.h index 1e42304..009ed9f 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_extension.h +++ b/third_party/protobuf/src/google/protobuf/compiler/java/java_extension.h @@ -60,7 +60,7 @@ class ExtensionGenerator { ~ExtensionGenerator(); void Generate(io::Printer* printer); - void GenerateInitializationCode(io::Printer* printer); + void GenerateNonNestedInitializationCode(io::Printer* printer); void GenerateRegistrationCode(io::Printer* printer); private: diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_field.cc b/third_party/protobuf/src/google/protobuf/compiler/java/java_field.cc index 978c8f3..c7d433c 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_field.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/java/java_field.cc @@ -37,6 +37,7 @@ #include <google/protobuf/compiler/java/java_primitive_field.h> #include <google/protobuf/compiler/java/java_enum_field.h> #include <google/protobuf/compiler/java/java_message_field.h> +#include <google/protobuf/compiler/java/java_string_field.h> #include <google/protobuf/stubs/common.h> namespace google { @@ -63,33 +64,57 @@ FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor) extension_generators_( new scoped_ptr<FieldGenerator>[descriptor->extension_count()]) { - // Construct all the FieldGenerators. + // Construct all the FieldGenerators and assign them bit indices for their + // bit fields. + int messageBitIndex = 0; + int builderBitIndex = 0; for (int i = 0; i < descriptor->field_count(); i++) { - field_generators_[i].reset(MakeGenerator(descriptor->field(i))); + FieldGenerator* generator = MakeGenerator(descriptor->field(i), + messageBitIndex, builderBitIndex); + field_generators_[i].reset(generator); + messageBitIndex += generator->GetNumBitsForMessage(); + builderBitIndex += generator->GetNumBitsForBuilder(); } for (int i = 0; i < descriptor->extension_count(); i++) { - extension_generators_[i].reset(MakeGenerator(descriptor->extension(i))); + FieldGenerator* generator = MakeGenerator(descriptor->extension(i), + messageBitIndex, builderBitIndex); + extension_generators_[i].reset(generator); + messageBitIndex += generator->GetNumBitsForMessage(); + builderBitIndex += generator->GetNumBitsForBuilder(); } } -FieldGenerator* FieldGeneratorMap::MakeGenerator(const FieldDescriptor* field) { +FieldGenerator* FieldGeneratorMap::MakeGenerator( + const FieldDescriptor* field, int messageBitIndex, int builderBitIndex) { if (field->is_repeated()) { switch (GetJavaType(field)) { case JAVATYPE_MESSAGE: - return new RepeatedMessageFieldGenerator(field); + return new RepeatedMessageFieldGenerator( + field, messageBitIndex, builderBitIndex); case JAVATYPE_ENUM: - return new RepeatedEnumFieldGenerator(field); + return new RepeatedEnumFieldGenerator( + field, messageBitIndex, builderBitIndex); + case JAVATYPE_STRING: + return new RepeatedStringFieldGenerator( + field, messageBitIndex, builderBitIndex); default: - return new RepeatedPrimitiveFieldGenerator(field); + return new RepeatedPrimitiveFieldGenerator( + field, messageBitIndex, builderBitIndex); } } else { switch (GetJavaType(field)) { case JAVATYPE_MESSAGE: - return new MessageFieldGenerator(field); + return new MessageFieldGenerator( + field, messageBitIndex, builderBitIndex); case JAVATYPE_ENUM: - return new EnumFieldGenerator(field); + return new EnumFieldGenerator( + field, messageBitIndex, builderBitIndex); + case JAVATYPE_STRING: + return new StringFieldGenerator( + field, messageBitIndex, builderBitIndex); default: - return new PrimitiveFieldGenerator(field); + return new PrimitiveFieldGenerator( + field, messageBitIndex, builderBitIndex); } } } diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_field.h b/third_party/protobuf/src/google/protobuf/compiler/java/java_field.h index f5bef7a..6097f35 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_field.h +++ b/third_party/protobuf/src/google/protobuf/compiler/java/java_field.h @@ -55,15 +55,24 @@ class FieldGenerator { FieldGenerator() {} virtual ~FieldGenerator(); + virtual int GetNumBitsForMessage() const = 0; + virtual int GetNumBitsForBuilder() const = 0; + virtual void GenerateInterfaceMembers(io::Printer* printer) const = 0; virtual void GenerateMembers(io::Printer* printer) const = 0; virtual void GenerateBuilderMembers(io::Printer* printer) const = 0; virtual void GenerateInitializationCode(io::Printer* printer) const = 0; + virtual void GenerateBuilderClearCode(io::Printer* printer) const = 0; virtual void GenerateMergingCode(io::Printer* printer) const = 0; virtual void GenerateBuildingCode(io::Printer* printer) const = 0; virtual void GenerateParsingCode(io::Printer* printer) const = 0; virtual void GenerateParsingCodeFromPacked(io::Printer* printer) const; virtual void GenerateSerializationCode(io::Printer* printer) const = 0; virtual void GenerateSerializedSizeCode(io::Printer* printer) const = 0; + virtual void GenerateFieldBuilderInitializationCode(io::Printer* printer) + const = 0; + + virtual void GenerateEqualsCode(io::Printer* printer) const = 0; + virtual void GenerateHashCode(io::Printer* printer) const = 0; virtual string GetBoxedType() const = 0; @@ -85,7 +94,8 @@ class FieldGeneratorMap { scoped_array<scoped_ptr<FieldGenerator> > field_generators_; scoped_array<scoped_ptr<FieldGenerator> > extension_generators_; - static FieldGenerator* MakeGenerator(const FieldDescriptor* field); + static FieldGenerator* MakeGenerator(const FieldDescriptor* field, + int messageBitIndex, int builderBitIndex); GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGeneratorMap); }; diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_file.cc b/third_party/protobuf/src/google/protobuf/compiler/java/java_file.cc index 7ea127c..8968069 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_file.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/java/java_file.cc @@ -88,7 +88,8 @@ bool UsesExtensions(const Message& message) { FileGenerator::FileGenerator(const FileDescriptor* file) : file_(file), java_package_(FileJavaPackage(file)), - classname_(FileClassName(file)) {} + classname_(FileClassName(file)) { +} FileGenerator::~FileGenerator() {} @@ -179,7 +180,9 @@ void FileGenerator::Generate(io::Printer* printer) { EnumGenerator(file_->enum_type(i)).Generate(printer); } for (int i = 0; i < file_->message_type_count(); i++) { - MessageGenerator(file_->message_type(i)).Generate(printer); + MessageGenerator messageGenerator(file_->message_type(i)); + messageGenerator.GenerateInterface(printer); + messageGenerator.Generate(printer); } if (HasGenericServices(file_)) { for (int i = 0; i < file_->service_count(); i++) { @@ -215,24 +218,11 @@ void FileGenerator::Generate(io::Printer* printer) { .GenerateStaticVariableInitializers(printer); } - for (int i = 0; i < file_->extension_count(); i++) { - // TODO(kenton): Reuse ExtensionGenerator objects? - ExtensionGenerator(file_->extension(i)) - .GenerateInitializationCode(printer); - } - printer->Outdent(); printer->Print( "}\n"); } - // Dummy function we can use to force the static initialization block to - // run. Needed by inner classes. Cannot be private due to - // java_multiple_files option. - printer->Print( - "\n" - "public static void internalForceInit() {}\n"); - printer->Print( "\n" "// @@protoc_insertion_point(outer_class_scope)\n"); @@ -310,11 +300,10 @@ void FileGenerator::GenerateEmbeddedDescriptor(io::Printer* printer) { MessageGenerator(file_->message_type(i)) .GenerateStaticVariableInitializers(printer); } - for (int i = 0; i < file_->extension_count(); i++) { // TODO(kenton): Reuse ExtensionGenerator objects? ExtensionGenerator(file_->extension(i)) - .GenerateInitializationCode(printer); + .GenerateNonNestedInitializationCode(printer); } if (UsesExtensions(file_proto)) { @@ -325,9 +314,11 @@ void FileGenerator::GenerateEmbeddedDescriptor(io::Printer* printer) { " com.google.protobuf.ExtensionRegistry.newInstance();\n" "registerAllExtensions(registry);\n"); for (int i = 0; i < file_->dependency_count(); i++) { - printer->Print( - "$dependency$.registerAllExtensions(registry);\n", - "dependency", ClassName(file_->dependency(i))); + if (ShouldIncludeDependency(file_->dependency(i))) { + printer->Print( + "$dependency$.registerAllExtensions(registry);\n", + "dependency", ClassName(file_->dependency(i))); + } } printer->Print( "return registry;\n"); @@ -372,13 +363,14 @@ template<typename GeneratorClass, typename DescriptorClass> static void GenerateSibling(const string& package_dir, const string& java_package, const DescriptorClass* descriptor, - OutputDirectory* output_directory, - vector<string>* file_list) { - string filename = package_dir + descriptor->name() + ".java"; + GeneratorContext* context, + vector<string>* file_list, + const string& name_suffix, + void (GeneratorClass::*pfn)(io::Printer* printer)) { + string filename = package_dir + descriptor->name() + name_suffix + ".java"; file_list->push_back(filename); - scoped_ptr<io::ZeroCopyOutputStream> output( - output_directory->Open(filename)); + scoped_ptr<io::ZeroCopyOutputStream> output(context->Open(filename)); io::Printer printer(output.get(), '$'); printer.Print( @@ -391,28 +383,36 @@ static void GenerateSibling(const string& package_dir, "package", java_package); } - GeneratorClass(descriptor).Generate(&printer); + GeneratorClass generator(descriptor); + (generator.*pfn)(&printer); } void FileGenerator::GenerateSiblings(const string& package_dir, - OutputDirectory* output_directory, + GeneratorContext* context, vector<string>* file_list) { if (file_->options().java_multiple_files()) { for (int i = 0; i < file_->enum_type_count(); i++) { GenerateSibling<EnumGenerator>(package_dir, java_package_, file_->enum_type(i), - output_directory, file_list); + context, file_list, "", + &EnumGenerator::Generate); } for (int i = 0; i < file_->message_type_count(); i++) { GenerateSibling<MessageGenerator>(package_dir, java_package_, file_->message_type(i), - output_directory, file_list); + context, file_list, "OrBuilder", + &MessageGenerator::GenerateInterface); + GenerateSibling<MessageGenerator>(package_dir, java_package_, + file_->message_type(i), + context, file_list, "", + &MessageGenerator::Generate); } if (HasGenericServices(file_)) { for (int i = 0; i < file_->service_count(); i++) { GenerateSibling<ServiceGenerator>(package_dir, java_package_, file_->service(i), - output_directory, file_list); + context, file_list, "", + &ServiceGenerator::Generate); } } } diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_file.h b/third_party/protobuf/src/google/protobuf/compiler/java/java_file.h index 9e35d33..5991146 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_file.h +++ b/third_party/protobuf/src/google/protobuf/compiler/java/java_file.h @@ -46,7 +46,7 @@ namespace protobuf { class Printer; // printer.h } namespace compiler { - class OutputDirectory; // code_generator.h + class GeneratorContext; // code_generator.h } } @@ -70,12 +70,13 @@ class FileGenerator { // files other than the outer file (i.e. one for each message, enum, and // service type). void GenerateSiblings(const string& package_dir, - OutputDirectory* output_directory, + GeneratorContext* generator_context, vector<string>* file_list); const string& java_package() { return java_package_; } const string& classname() { return classname_; } + private: // Returns whether the dependency should be included in the output file. // Always returns true for opensource, but used internally at Google to help @@ -86,6 +87,7 @@ class FileGenerator { string java_package_; string classname_; + void GenerateEmbeddedDescriptor(io::Printer* printer); GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileGenerator); diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_generator.cc b/third_party/protobuf/src/google/protobuf/compiler/java/java_generator.cc index 745b55a..e6c79ab 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_generator.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/java/java_generator.cc @@ -51,11 +51,8 @@ JavaGenerator::~JavaGenerator() {} bool JavaGenerator::Generate(const FileDescriptor* file, const string& parameter, - OutputDirectory* output_directory, + GeneratorContext* context, string* error) const { - vector<pair<string, string> > options; - ParseGeneratorParameter(parameter, &options); - // ----------------------------------------------------------------- // parse generator options @@ -63,6 +60,10 @@ bool JavaGenerator::Generate(const FileDescriptor* file, // per line. string output_list_file; + + vector<pair<string, string> > options; + ParseGeneratorParameter(parameter, &options); + for (int i = 0; i < options.size(); i++) { if (options[i].first == "output_list_file") { output_list_file = options[i].second; @@ -72,18 +73,23 @@ bool JavaGenerator::Generate(const FileDescriptor* file, } } - // ----------------------------------------------------------------- + if (file->options().optimize_for() == FileOptions::LITE_RUNTIME && + file->options().java_generate_equals_and_hash()) { + *error = "The \"java_generate_equals_and_hash\" option is incompatible " + "with \"optimize_for = LITE_RUNTIME\". You must optimize for " + "SPEED or CODE_SIZE if you want to use this option."; + return false; + } + FileGenerator file_generator(file); if (!file_generator.Validate(error)) { return false; } - string package_dir = - StringReplace(file_generator.java_package(), ".", "/", true); - if (!package_dir.empty()) package_dir += "/"; + string package_dir = JavaPackageToDir(file_generator.java_package()); vector<string> all_files; @@ -94,19 +100,19 @@ bool JavaGenerator::Generate(const FileDescriptor* file, // Generate main java file. scoped_ptr<io::ZeroCopyOutputStream> output( - output_directory->Open(java_filename)); + context->Open(java_filename)); io::Printer printer(output.get(), '$'); file_generator.Generate(&printer); // Generate sibling files. - file_generator.GenerateSiblings(package_dir, output_directory, &all_files); + file_generator.GenerateSiblings(package_dir, context, &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)); + context->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]); diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_generator.h b/third_party/protobuf/src/google/protobuf/compiler/java/java_generator.h index c91c905..888b8d8 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_generator.h +++ b/third_party/protobuf/src/google/protobuf/compiler/java/java_generator.h @@ -57,7 +57,7 @@ class LIBPROTOC_EXPORT JavaGenerator : public CodeGenerator { // implements CodeGenerator ---------------------------------------- bool Generate(const FileDescriptor* file, const string& parameter, - OutputDirectory* output_directory, + GeneratorContext* context, string* error) const; private: diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_helpers.cc b/third_party/protobuf/src/google/protobuf/compiler/java/java_helpers.cc index 7ed0c3c..1b6f165 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_helpers.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/java/java_helpers.cc @@ -134,16 +134,27 @@ string FileClassName(const FileDescriptor* file) { } string FileJavaPackage(const FileDescriptor* file) { + string result; + if (file->options().has_java_package()) { - return file->options().java_package(); + result = file->options().java_package(); } else { - string result = kDefaultPackage; + result = kDefaultPackage; if (!file->package().empty()) { if (!result.empty()) result += '.'; result += file->package(); } - return result; } + + + return result; +} + +string JavaPackageToDir(string package_name) { + string package_dir = + StringReplace(package_name, ".", "/", true); + if (!package_dir.empty()) package_dir += "/"; + return package_dir; } string ToJavaName(const string& full_name, const FileDescriptor* file) { @@ -335,6 +346,132 @@ string DefaultValue(const FieldDescriptor* field) { return ""; } +bool IsDefaultValueJavaDefault(const FieldDescriptor* field) { + // Switch on CppType since we need to know which default_value_* method + // of FieldDescriptor to call. + switch (field->cpp_type()) { + case FieldDescriptor::CPPTYPE_INT32: + return field->default_value_int32() == 0; + case FieldDescriptor::CPPTYPE_UINT32: + return field->default_value_uint32() == 0; + case FieldDescriptor::CPPTYPE_INT64: + return field->default_value_int64() == 0L; + case FieldDescriptor::CPPTYPE_UINT64: + return field->default_value_uint64() == 0L; + case FieldDescriptor::CPPTYPE_DOUBLE: + return field->default_value_double() == 0.0; + case FieldDescriptor::CPPTYPE_FLOAT: + return field->default_value_float() == 0.0; + case FieldDescriptor::CPPTYPE_BOOL: + return field->default_value_bool() == false; + + case FieldDescriptor::CPPTYPE_STRING: + case FieldDescriptor::CPPTYPE_ENUM: + case FieldDescriptor::CPPTYPE_MESSAGE: + return false; + + // No default because we want the compiler to complain if any new + // types are added. + } + + GOOGLE_LOG(FATAL) << "Can't get here."; + return false; +} + +const char* bit_masks[] = { + "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 varName = "bitField"; + varName += SimpleItoa(index); + varName += "_"; + return varName; +} + +string GetBitFieldNameForBit(int bitIndex) { + return GetBitFieldName(bitIndex / 32); +} + +string GenerateGetBit(int bitIndex) { + string varName = GetBitFieldNameForBit(bitIndex); + int bitInVarIndex = bitIndex % 32; + + string mask = bit_masks[bitInVarIndex]; + string result = "((" + varName + " & " + mask + ") == " + mask + ")"; + return result; +} + +string GenerateSetBit(int bitIndex) { + string varName = GetBitFieldNameForBit(bitIndex); + int bitInVarIndex = bitIndex % 32; + + string mask = bit_masks[bitInVarIndex]; + string result = varName + " |= " + mask; + return result; +} + +string GenerateClearBit(int bitIndex) { + string varName = GetBitFieldNameForBit(bitIndex); + int bitInVarIndex = bitIndex % 32; + + string mask = bit_masks[bitInVarIndex]; + string result = varName + " = (" + varName + " & ~" + mask + ")"; + return result; +} + +string GenerateGetBitFromLocal(int bitIndex) { + string varName = "from_" + GetBitFieldNameForBit(bitIndex); + int bitInVarIndex = bitIndex % 32; + + string mask = bit_masks[bitInVarIndex]; + string result = "((" + varName + " & " + mask + ") == " + mask + ")"; + return result; +} + +string GenerateSetBitToLocal(int bitIndex) { + string varName = "to_" + GetBitFieldNameForBit(bitIndex); + int bitInVarIndex = bitIndex % 32; + + string mask = bit_masks[bitInVarIndex]; + string result = varName + " |= " + mask; + return result; +} + } // namespace java } // namespace compiler } // namespace protobuf diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_helpers.h b/third_party/protobuf/src/google/protobuf/compiler/java/java_helpers.h index 002e177..88efd45 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_helpers.h +++ b/third_party/protobuf/src/google/protobuf/compiler/java/java_helpers.h @@ -68,6 +68,9 @@ string FileClassName(const FileDescriptor* file); // Returns the file's Java package name. string FileJavaPackage(const FileDescriptor* file); +// Returns output directory for the given package name. +string JavaPackageToDir(string package_name); + // Converts the given fully-qualified name in the proto namespace to its // fully-qualified name in the Java namespace, given that it is in the given // file. @@ -118,6 +121,7 @@ JavaType GetJavaType(const FieldDescriptor* field); const char* BoxedPrimitiveTypeName(JavaType type); string DefaultValue(const FieldDescriptor* field); +bool IsDefaultValueJavaDefault(const FieldDescriptor* field); // Does this message class keep track of unknown fields? inline bool HasUnknownFields(const Descriptor* descriptor) { @@ -133,6 +137,11 @@ inline bool HasGeneratedMethods(const Descriptor* descriptor) { FileOptions::CODE_SIZE; } +// Does this message have specialized equals() and hashCode() methods? +inline bool HasEqualsAndHashCode(const Descriptor* descriptor) { + return descriptor->file()->options().java_generate_equals_and_hash(); +} + // Does this message class have descriptor and reflection methods? inline bool HasDescriptorMethods(const Descriptor* descriptor) { return descriptor->file()->options().optimize_for() != @@ -147,6 +156,12 @@ inline bool HasDescriptorMethods(const FileDescriptor* descriptor) { FileOptions::LITE_RUNTIME; } +inline bool HasNestedBuilders(const Descriptor* descriptor) { + // The proto-lite version doesn't support nested builders. + return descriptor->file()->options().optimize_for() != + FileOptions::LITE_RUNTIME; +} + // Should we generate generic services for this file? inline bool HasGenericServices(const FileDescriptor *file) { return file->service_count() > 0 && @@ -154,6 +169,43 @@ inline bool HasGenericServices(const FileDescriptor *file) { file->options().java_generic_services(); } + +// Methods for shared bitfields. + +// Gets the name of the shared bitfield for the given index. +string GetBitFieldName(int index); + +// Gets the name of the shared bitfield for the given bit index. +// Effectively, GetBitFieldName(bitIndex / 32) +string GetBitFieldNameForBit(int bitIndex); + +// Generates the java code for the expression that returns the boolean value +// of the bit of the shared bitfields for the given bit index. +// Example: "((bitField1_ & 0x04) == 0x04)" +string GenerateGetBit(int bitIndex); + +// Generates the java code for the expression that sets the bit of the shared +// bitfields for the given bit index. +// Example: "bitField1_ = (bitField1_ | 0x04)" +string GenerateSetBit(int bitIndex); + +// Generates the java code for the expression that clears the bit of the shared +// bitfields for the given bit index. +// Example: "bitField1_ = (bitField1_ & ~0x04)" +string GenerateClearBit(int bitIndex); + +// Does the same as GenerateGetBit but operates on the bit field on a local +// variable. This is used by the builder to copy the value in the builder to +// the message. +// Example: "((from_bitField1_ & 0x04) == 0x04)" +string GenerateGetBitFromLocal(int bitIndex); + +// Does the same as GenerateSetBit but operates on the bit field on a local +// variable. This is used by the builder to copy the value in the builder to +// the message. +// Example: "to_bitField1_ = (to_bitField1_ | 0x04)" +string GenerateSetBitToLocal(int bitIndex); + } // namespace java } // namespace compiler } // namespace protobuf diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_message.cc b/third_party/protobuf/src/google/protobuf/compiler/java/java_message.cc index 8b91193..47ee84c 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_message.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/java/java_message.cc @@ -245,14 +245,54 @@ void MessageGenerator::GenerateStaticVariableInitializers( MessageGenerator(descriptor_->nested_type(i)) .GenerateStaticVariableInitializers(printer); } +} - for (int i = 0; i < descriptor_->extension_count(); i++) { - // TODO(kenton): Reuse ExtensionGenerator objects? - ExtensionGenerator(descriptor_->extension(i)) - .GenerateInitializationCode(printer); +// =================================================================== + +void MessageGenerator::GenerateInterface(io::Printer* printer) { + + if (descriptor_->extension_range_count() > 0) { + if (HasDescriptorMethods(descriptor_)) { + printer->Print( + "public interface $classname$OrBuilder extends\n" + " com.google.protobuf.GeneratedMessage.\n" + " ExtendableMessageOrBuilder<$classname$> {\n", + "classname", descriptor_->name()); + } else { + printer->Print( + "public interface $classname$OrBuilder extends \n" + " com.google.protobuf.GeneratedMessageLite.\n" + " ExtendableMessageOrBuilder<$classname$> {\n", + "classname", descriptor_->name()); + } + } else { + if (HasDescriptorMethods(descriptor_)) { + printer->Print( + "public interface $classname$OrBuilder\n" + " extends com.google.protobuf.MessageOrBuilder {\n", + "classname", descriptor_->name()); + } else { + printer->Print( + "public interface $classname$OrBuilder\n" + " extends com.google.protobuf.MessageLiteOrBuilder {\n", + "classname", descriptor_->name()); + } } + + printer->Indent(); + for (int i = 0; i < descriptor_->field_count(); i++) { + printer->Print("\n"); + PrintFieldComment(printer, descriptor_->field(i)); + field_generators_.get(descriptor_->field(i)) + .GenerateInterfaceMembers(printer); + } + printer->Outdent(); + + printer->Print("}\n"); } +// =================================================================== + void MessageGenerator::Generate(io::Printer* printer) { bool is_own_file = descriptor_->containing_type() == NULL && @@ -263,14 +303,14 @@ void MessageGenerator::Generate(io::Printer* printer) { printer->Print( "public $static$ final class $classname$ extends\n" " com.google.protobuf.GeneratedMessage.ExtendableMessage<\n" - " $classname$> {\n", + " $classname$> implements $classname$OrBuilder {\n", "static", is_own_file ? "" : "static", "classname", descriptor_->name()); } else { printer->Print( "public $static$ final class $classname$ extends\n" " com.google.protobuf.GeneratedMessageLite.ExtendableMessage<\n" - " $classname$> {\n", + " $classname$> implements $classname$OrBuilder {\n", "static", is_own_file ? "" : "static", "classname", descriptor_->name()); } @@ -278,13 +318,15 @@ void MessageGenerator::Generate(io::Printer* printer) { if (HasDescriptorMethods(descriptor_)) { printer->Print( "public $static$ final class $classname$ extends\n" - " com.google.protobuf.GeneratedMessage {\n", + " com.google.protobuf.GeneratedMessage\n" + " implements $classname$OrBuilder {\n", "static", is_own_file ? "" : "static", "classname", descriptor_->name()); } else { printer->Print( "public $static$ final class $classname$ extends\n" - " com.google.protobuf.GeneratedMessageLite {\n", + " com.google.protobuf.GeneratedMessageLite\n" + " implements $classname$OrBuilder {\n", "static", is_own_file ? "" : "static", "classname", descriptor_->name()); } @@ -292,8 +334,8 @@ void MessageGenerator::Generate(io::Printer* printer) { printer->Indent(); printer->Print( "// Use $classname$.newBuilder() to construct.\n" - "private $classname$() {\n" - " initFields();\n" + "private $classname$(Builder builder) {\n" + " super(builder);\n" "}\n" // Used when constructing the default instance, which cannot be initialized // immediately because it may cyclically refer to other default instances. @@ -310,33 +352,29 @@ void MessageGenerator::Generate(io::Printer* printer) { "\n", "classname", descriptor_->name()); - if (HasDescriptorMethods(descriptor_)) { - printer->Print( - "public static final com.google.protobuf.Descriptors.Descriptor\n" - " getDescriptor() {\n" - " return $fileclass$.internal_$identifier$_descriptor;\n" - "}\n" - "\n" - "protected com.google.protobuf.GeneratedMessage.FieldAccessorTable\n" - " internalGetFieldAccessorTable() {\n" - " return $fileclass$.internal_$identifier$_fieldAccessorTable;\n" - "}\n" - "\n", - "fileclass", ClassName(descriptor_->file()), - "identifier", UniqueFileScopeIdentifier(descriptor_)); - } + GenerateDescriptorMethods(printer); - // Nested types and extensions + // Nested types for (int i = 0; i < descriptor_->enum_type_count(); i++) { EnumGenerator(descriptor_->enum_type(i)).Generate(printer); } for (int i = 0; i < descriptor_->nested_type_count(); i++) { - MessageGenerator(descriptor_->nested_type(i)).Generate(printer); + MessageGenerator messageGenerator(descriptor_->nested_type(i)); + messageGenerator.GenerateInterface(printer); + messageGenerator.Generate(printer); } - for (int i = 0; i < descriptor_->extension_count(); i++) { - ExtensionGenerator(descriptor_->extension(i)).Generate(printer); + // Integers for bit fields. + int totalBits = 0; + for (int i = 0; i < descriptor_->field_count(); i++) { + totalBits += field_generators_.get(descriptor_->field(i)) + .GetNumBitsForMessage(); + } + int totalInts = (totalBits + 31) / 32; + for (int i = 0; i < totalInts; i++) { + printer->Print("private int $bit_field_name$;\n", + "bit_field_name", GetBitFieldName(i)); } // Fields @@ -361,35 +399,42 @@ void MessageGenerator::Generate(io::Printer* printer) { printer->Print("}\n"); if (HasGeneratedMethods(descriptor_)) { - GenerateIsInitialized(printer); + GenerateIsInitialized(printer, MEMOIZE); GenerateMessageSerializationMethods(printer); } + if (HasEqualsAndHashCode(descriptor_)) { + GenerateEqualsAndHashCode(printer); + } + GenerateParseFromMethods(printer); GenerateBuilder(printer); - // Force initialization of outer class. Otherwise, nested extensions may - // not be initialized. Also carefully initialize the default instance in - // such a way that it doesn't conflict with other initialization. + // Carefully initialize the default instance in such a way that it doesn't + // conflict with other initialization. printer->Print( "\n" "static {\n" " defaultInstance = new $classname$(true);\n" - " $file$.internalForceInit();\n" " defaultInstance.initFields();\n" - "}\n", - "file", ClassName(descriptor_->file()), - "classname", descriptor_->name()); - - printer->Print( + "}\n" "\n" "// @@protoc_insertion_point(class_scope:$full_name$)\n", + "classname", descriptor_->name(), "full_name", descriptor_->full_name()); + // Extensions must be declared after the defaultInstance is initialized + // because the defaultInstance is used by the extension to lazily retrieve + // the outer class's FileDescriptor. + for (int i = 0; i < descriptor_->extension_count(); i++) { + ExtensionGenerator(descriptor_->extension(i)).Generate(printer); + } + printer->Outdent(); printer->Print("}\n\n"); } + // =================================================================== void MessageGenerator:: @@ -502,6 +547,13 @@ GenerateMessageSerializationMethods(io::Printer* printer) { " return size;\n" "}\n" "\n"); + + printer->Print( + "@java.lang.Override\n" + "protected Object writeReplace() throws java.io.ObjectStreamException {\n" + " return super.writeReplace();\n" + "}\n" + "\n"); } void MessageGenerator:: @@ -605,42 +657,68 @@ void MessageGenerator::GenerateBuilder(io::Printer* printer) { "\n", "classname", ClassName(descriptor_)); + if (HasNestedBuilders(descriptor_)) { + printer->Print( + "@java.lang.Override\n" + "protected Builder newBuilderForType(\n" + " com.google.protobuf.GeneratedMessage.BuilderParent parent) {\n" + " Builder builder = new Builder(parent);\n" + " return builder;\n" + "}\n"); + } + if (descriptor_->extension_range_count() > 0) { if (HasDescriptorMethods(descriptor_)) { printer->Print( "public static final class Builder extends\n" " com.google.protobuf.GeneratedMessage.ExtendableBuilder<\n" - " $classname$, Builder> {\n", + " $classname$, Builder> implements $classname$OrBuilder {\n", "classname", ClassName(descriptor_)); } else { printer->Print( "public static final class Builder extends\n" " com.google.protobuf.GeneratedMessageLite.ExtendableBuilder<\n" - " $classname$, Builder> {\n", + " $classname$, Builder> implements $classname$OrBuilder {\n", "classname", ClassName(descriptor_)); } } else { if (HasDescriptorMethods(descriptor_)) { printer->Print( "public static final class Builder extends\n" - " com.google.protobuf.GeneratedMessage.Builder<Builder> {\n", + " com.google.protobuf.GeneratedMessage.Builder<Builder>\n" + " implements $classname$OrBuilder {\n", "classname", ClassName(descriptor_)); } else { printer->Print( "public static final class Builder extends\n" " com.google.protobuf.GeneratedMessageLite.Builder<\n" - " $classname$, Builder> {\n", + " $classname$, Builder>\n" + " implements $classname$OrBuilder {\n", "classname", ClassName(descriptor_)); } } printer->Indent(); + GenerateDescriptorMethods(printer); GenerateCommonBuilderMethods(printer); if (HasGeneratedMethods(descriptor_)) { + GenerateIsInitialized(printer, DONT_MEMOIZE); GenerateBuilderParsingMethods(printer); } + // Integers for bit fields. + int totalBits = 0; + for (int i = 0; i < descriptor_->field_count(); i++) { + totalBits += field_generators_.get(descriptor_->field(i)) + .GetNumBitsForBuilder(); + } + int totalInts = (totalBits + 31) / 32; + for (int i = 0; i < totalInts; i++) { + printer->Print("private int $bit_field_name$;\n", + "bit_field_name", GetBitFieldName(i)); + } + for (int i = 0; i < descriptor_->field_count(); i++) { printer->Print("\n"); PrintFieldComment(printer, descriptor_->field(i)); @@ -657,36 +735,92 @@ void MessageGenerator::GenerateBuilder(io::Printer* printer) { printer->Print("}\n"); } +void MessageGenerator::GenerateDescriptorMethods(io::Printer* printer) { + if (HasDescriptorMethods(descriptor_)) { + printer->Print( + "public static final com.google.protobuf.Descriptors.Descriptor\n" + " getDescriptor() {\n" + " return $fileclass$.internal_$identifier$_descriptor;\n" + "}\n" + "\n" + "protected com.google.protobuf.GeneratedMessage.FieldAccessorTable\n" + " internalGetFieldAccessorTable() {\n" + " return $fileclass$.internal_$identifier$_fieldAccessorTable;\n" + "}\n" + "\n", + "fileclass", ClassName(descriptor_->file()), + "identifier", UniqueFileScopeIdentifier(descriptor_)); + } +} + // =================================================================== void MessageGenerator::GenerateCommonBuilderMethods(io::Printer* printer) { printer->Print( - "private $classname$ result;\n" - "\n" "// Construct using $classname$.newBuilder()\n" - "private Builder() {}\n" - "\n" - "private static Builder create() {\n" - " Builder builder = new Builder();\n" - " builder.result = new $classname$();\n" - " return builder;\n" + "private Builder() {\n" + " maybeForceBuilderInitialization();\n" "}\n" - "\n" - "protected $classname$ internalGetResult() {\n" - " return result;\n" + "\n", + "classname", ClassName(descriptor_)); + + if (HasDescriptorMethods(descriptor_)) { + printer->Print( + "private Builder(BuilderParent parent) {\n" + " super(parent);\n" + " maybeForceBuilderInitialization();\n" + "}\n", + "classname", ClassName(descriptor_)); + } + + + if (HasNestedBuilders(descriptor_)) { + printer->Print( + "private void maybeForceBuilderInitialization() {\n" + " if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {\n"); + + printer->Indent(); + printer->Indent(); + for (int i = 0; i < descriptor_->field_count(); i++) { + field_generators_.get(descriptor_->field(i)) + .GenerateFieldBuilderInitializationCode(printer); + } + printer->Outdent(); + printer->Outdent(); + + printer->Print( + " }\n" + "}\n"); + } else { + printer->Print( + "private void maybeForceBuilderInitialization() {\n" + "}\n"); + } + + printer->Print( + "private static Builder create() {\n" + " return new Builder();\n" "}\n" "\n" "public Builder clear() {\n" - " if (result == null) {\n" - " throw new IllegalStateException(\n" - " \"Cannot call clear() after build().\");\n" - " }\n" - " result = new $classname$();\n" + " super.clear();\n", + "classname", ClassName(descriptor_)); + + printer->Indent(); + + for (int i = 0; i < descriptor_->field_count(); i++) { + field_generators_.get(descriptor_->field(i)) + .GenerateBuilderClearCode(printer); + } + + printer->Outdent(); + + printer->Print( " return this;\n" "}\n" "\n" "public Builder clone() {\n" - " return create().mergeFrom(result);\n" + " return create().mergeFrom(buildPartial());\n" "}\n" "\n", "classname", ClassName(descriptor_)); @@ -703,49 +837,78 @@ void MessageGenerator::GenerateCommonBuilderMethods(io::Printer* printer) { "public $classname$ getDefaultInstanceForType() {\n" " return $classname$.getDefaultInstance();\n" "}\n" - "\n" - "public boolean isInitialized() {\n" - " return result.isInitialized();\n" - "}\n", + "\n", "classname", ClassName(descriptor_)); // ----------------------------------------------------------------- printer->Print( "public $classname$ build() {\n" - // If result == null, we'll throw an appropriate exception later. - " if (result != null && !isInitialized()) {\n" + " $classname$ result = buildPartial();\n" + " if (!result.isInitialized()) {\n" " throw newUninitializedMessageException(result);\n" " }\n" - " return buildPartial();\n" + " return result;\n" "}\n" "\n" "private $classname$ buildParsed()\n" " throws com.google.protobuf.InvalidProtocolBufferException {\n" - " if (!isInitialized()) {\n" + " $classname$ result = buildPartial();\n" + " if (!result.isInitialized()) {\n" " throw newUninitializedMessageException(\n" " result).asInvalidProtocolBufferException();\n" " }\n" - " return buildPartial();\n" + " return result;\n" "}\n" "\n" "public $classname$ buildPartial() {\n" - " if (result == null) {\n" - " throw new IllegalStateException(\n" - " \"build() has already been called on this Builder.\");\n" - " }\n", + " $classname$ result = new $classname$(this);\n", "classname", ClassName(descriptor_)); + printer->Indent(); + // Local vars for from and to bit fields to avoid accessing the builder and + // message over and over for these fields. Seems to provide a slight + // perforamance improvement in micro benchmark and this is also what proto1 + // code does. + int totalBuilderBits = 0; + int totalMessageBits = 0; + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldGenerator& field = field_generators_.get(descriptor_->field(i)); + totalBuilderBits += field.GetNumBitsForBuilder(); + totalMessageBits += field.GetNumBitsForMessage(); + } + int totalBuilderInts = (totalBuilderBits + 31) / 32; + int totalMessageInts = (totalMessageBits + 31) / 32; + for (int i = 0; i < totalBuilderInts; i++) { + printer->Print("int from_$bit_field_name$ = $bit_field_name$;\n", + "bit_field_name", GetBitFieldName(i)); + } + for (int i = 0; i < totalMessageInts; i++) { + printer->Print("int to_$bit_field_name$ = 0;\n", + "bit_field_name", GetBitFieldName(i)); + } + + // Output generation code for each field. for (int i = 0; i < descriptor_->field_count(); i++) { field_generators_.get(descriptor_->field(i)).GenerateBuildingCode(printer); } + // Copy the bit field results to the generated message + for (int i = 0; i < totalMessageInts; i++) { + printer->Print("result.$bit_field_name$ = to_$bit_field_name$;\n", + "bit_field_name", GetBitFieldName(i)); + } + printer->Outdent(); + + if (HasDescriptorMethods(descriptor_)) { + printer->Print( + " onBuilt();\n"); + } + printer->Print( - " $classname$ returnMe = result;\n" - " result = null;\n" - " return returnMe;\n" + " return result;\n" "}\n" "\n", "classname", ClassName(descriptor_)); @@ -834,25 +997,31 @@ void MessageGenerator::GenerateBuilderParsingMethods(io::Printer* printer) { printer->Print( "case 0:\n" // zero signals EOF / limit reached " this.setUnknownFields(unknownFields.build());\n" + " $on_changed$\n" " return this;\n" "default: {\n" " if (!parseUnknownField(input, unknownFields,\n" " extensionRegistry, tag)) {\n" " this.setUnknownFields(unknownFields.build());\n" + " $on_changed$\n" " return this;\n" // it's an endgroup tag " }\n" " break;\n" - "}\n"); + "}\n", + "on_changed", HasDescriptorMethods(descriptor_) ? "onChanged();" : ""); } else { printer->Print( "case 0:\n" // zero signals EOF / limit reached + " $on_changed$\n" " return this;\n" "default: {\n" " if (!parseUnknownField(input, extensionRegistry, tag)) {\n" + " $on_changed$\n" " return this;\n" // it's an endgroup tag " }\n" " break;\n" - "}\n"); + "}\n", + "on_changed", HasDescriptorMethods(descriptor_) ? "onChanged();" : ""); } for (int i = 0; i < descriptor_->field_count(); i++) { @@ -898,16 +1067,33 @@ void MessageGenerator::GenerateBuilderParsingMethods(io::Printer* printer) { " }\n" // switch (tag) " }\n" // while (true) "}\n" + "\n"); } // =================================================================== -void MessageGenerator::GenerateIsInitialized(io::Printer* printer) { +void MessageGenerator::GenerateIsInitialized( + io::Printer* printer, UseMemoization useMemoization) { + bool memoization = useMemoization == MEMOIZE; + if (memoization) { + // Memoizes whether the protocol buffer is fully initialized (has all + // required fields). -1 means not yet computed. 0 means false and 1 means + // true. + printer->Print( + "private byte memoizedIsInitialized = -1;\n"); + } printer->Print( "public final boolean isInitialized() {\n"); printer->Indent(); + if (memoization) { + printer->Print( + "byte isInitialized = memoizedIsInitialized;\n" + "if (isInitialized != -1) return isInitialized == 1;\n" + "\n"); + } + // Check that all required fields in this message are set. // TODO(kenton): We can optimize this when we switch to putting all the // "has" fields into a single bitfield. @@ -916,8 +1102,12 @@ void MessageGenerator::GenerateIsInitialized(io::Printer* printer) { if (field->is_required()) { printer->Print( - "if (!has$name$) return false;\n", - "name", UnderscoresToCapitalizedCamelCase(field)); + "if (!has$name$()) {\n" + " $memoize$\n" + " return false;\n" + "}\n", + "name", UnderscoresToCapitalizedCamelCase(field), + "memoize", memoization ? "memoizedIsInitialized = 0;" : ""); } } @@ -929,25 +1119,37 @@ void MessageGenerator::GenerateIsInitialized(io::Printer* printer) { switch (field->label()) { case FieldDescriptor::LABEL_REQUIRED: printer->Print( - "if (!get$name$().isInitialized()) return false;\n", + "if (!get$name$().isInitialized()) {\n" + " $memoize$\n" + " return false;\n" + "}\n", "type", ClassName(field->message_type()), - "name", UnderscoresToCapitalizedCamelCase(field)); + "name", UnderscoresToCapitalizedCamelCase(field), + "memoize", memoization ? "memoizedIsInitialized = 0;" : ""); break; case FieldDescriptor::LABEL_OPTIONAL: printer->Print( "if (has$name$()) {\n" - " if (!get$name$().isInitialized()) return false;\n" + " if (!get$name$().isInitialized()) {\n" + " $memoize$\n" + " return false;\n" + " }\n" "}\n", "type", ClassName(field->message_type()), - "name", UnderscoresToCapitalizedCamelCase(field)); + "name", UnderscoresToCapitalizedCamelCase(field), + "memoize", memoization ? "memoizedIsInitialized = 0;" : ""); break; case FieldDescriptor::LABEL_REPEATED: printer->Print( - "for ($type$ element : get$name$List()) {\n" - " if (!element.isInitialized()) return false;\n" + "for (int i = 0; i < get$name$Count(); i++) {\n" + " if (!get$name$(i).isInitialized()) {\n" + " $memoize$\n" + " return false;\n" + " }\n" "}\n", "type", ClassName(field->message_type()), - "name", UnderscoresToCapitalizedCamelCase(field)); + "name", UnderscoresToCapitalizedCamelCase(field), + "memoize", memoization ? "memoizedIsInitialized = 0;" : ""); break; } } @@ -955,10 +1157,20 @@ void MessageGenerator::GenerateIsInitialized(io::Printer* printer) { if (descriptor_->extension_range_count() > 0) { printer->Print( - "if (!extensionsAreInitialized()) return false;\n"); + "if (!extensionsAreInitialized()) {\n" + " $memoize$\n" + " return false;\n" + "}\n", + "memoize", memoization ? "memoizedIsInitialized = 0;" : ""); } printer->Outdent(); + + if (memoization) { + printer->Print( + " memoizedIsInitialized = 1;\n"); + } + printer->Print( " return true;\n" "}\n" @@ -967,6 +1179,94 @@ void MessageGenerator::GenerateIsInitialized(io::Printer* printer) { // =================================================================== +void MessageGenerator::GenerateEqualsAndHashCode(io::Printer* printer) { + printer->Print( + "@java.lang.Override\n" + "public boolean equals(final Object obj) {\n"); + printer->Indent(); + printer->Print( + "if (obj == this) {\n" + " return true;\n" + "}\n" + "if (!(obj instanceof $classname$)) {\n" + " return super.equals(obj);\n" + "}\n" + "$classname$ other = ($classname$) obj;\n" + "\n", + "classname", ClassName(descriptor_)); + + printer->Print("boolean result = true;\n"); + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = descriptor_->field(i); + if (!field->is_repeated()) { + printer->Print( + "result = result && (has$name$() == other.has$name$());\n" + "if (has$name$()) {\n", + "name", UnderscoresToCapitalizedCamelCase(field)); + printer->Indent(); + } + field_generators_.get(field).GenerateEqualsCode(printer); + if (!field->is_repeated()) { + printer->Outdent(); + printer->Print( + "}\n"); + } + } + if (HasDescriptorMethods(descriptor_)) { + printer->Print( + "result = result &&\n" + " getUnknownFields().equals(other.getUnknownFields());\n"); + if (descriptor_->extension_range_count() > 0) { + printer->Print( + "result = result &&\n" + " getExtensionFields().equals(other.getExtensionFields());\n"); + } + } + printer->Print( + "return result;\n"); + printer->Outdent(); + printer->Print( + "}\n" + "\n"); + + printer->Print( + "@java.lang.Override\n" + "public int hashCode() {\n"); + printer->Indent(); + printer->Print( + "int hash = 41;\n" + "hash = (19 * hash) + getDescriptorForType().hashCode();\n"); + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = descriptor_->field(i); + if (!field->is_repeated()) { + printer->Print( + "if (has$name$()) {\n", + "name", UnderscoresToCapitalizedCamelCase(field)); + printer->Indent(); + } + field_generators_.get(field).GenerateHashCode(printer); + if (!field->is_repeated()) { + printer->Outdent(); + printer->Print("}\n"); + } + } + if (HasDescriptorMethods(descriptor_)) { + if (descriptor_->extension_range_count() > 0) { + printer->Print( + "hash = hashFields(hash, getExtensionFields());\n"); + } + } + printer->Print( + "hash = (29 * hash) + getUnknownFields().hashCode();\n" + "return hash;\n"); + printer->Outdent(); + printer->Print( + "}\n" + "\n"); +} + +// =================================================================== + void MessageGenerator::GenerateExtensionRegistrationCode(io::Printer* printer) { for (int i = 0; i < descriptor_->extension_count(); i++) { ExtensionGenerator(descriptor_->extension(i)) diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_message.h b/third_party/protobuf/src/google/protobuf/compiler/java/java_message.h index 50ffae0..4c6fbbe 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_message.h +++ b/third_party/protobuf/src/google/protobuf/compiler/java/java_message.h @@ -67,11 +67,19 @@ class MessageGenerator { // Generate the class itself. void Generate(io::Printer* printer); + // Generates the base interface that both the class and its builder implement + void GenerateInterface(io::Printer* printer); + // Generate code to register all contained extensions with an // ExtensionRegistry. void GenerateExtensionRegistrationCode(io::Printer* printer); private: + enum UseMemoization { + MEMOIZE, + DONT_MEMOIZE + }; + void GenerateMessageSerializationMethods(io::Printer* printer); void GenerateParseFromMethods(io::Printer* printer); void GenerateSerializeOneField(io::Printer* printer, @@ -81,8 +89,11 @@ class MessageGenerator { void GenerateBuilder(io::Printer* printer); void GenerateCommonBuilderMethods(io::Printer* printer); + void GenerateDescriptorMethods(io::Printer* printer); void GenerateBuilderParsingMethods(io::Printer* printer); - void GenerateIsInitialized(io::Printer* printer); + void GenerateIsInitialized(io::Printer* printer, + UseMemoization useMemoization); + void GenerateEqualsAndHashCode(io::Printer* printer); const Descriptor* descriptor_; FieldGeneratorMap field_generators_; diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_message_field.cc b/third_party/protobuf/src/google/protobuf/compiler/java/java_message_field.cc index 71edc02..251945a 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_message_field.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/java/java_message_field.cc @@ -51,16 +51,43 @@ namespace { // TODO(kenton): Factor out a "SetCommonFieldVariables()" to get rid of // repeat code between this and the other field types. void SetMessageVariables(const FieldDescriptor* descriptor, + int messageBitIndex, + int builderBitIndex, map<string, string>* variables) { (*variables)["name"] = UnderscoresToCamelCase(descriptor); (*variables)["capitalized_name"] = UnderscoresToCapitalizedCamelCase(descriptor); + (*variables)["constant_name"] = FieldConstantName(descriptor); (*variables)["number"] = SimpleItoa(descriptor->number()); (*variables)["type"] = ClassName(descriptor->message_type()); (*variables)["group_or_message"] = (GetType(descriptor) == FieldDescriptor::TYPE_GROUP) ? "Group" : "Message"; + // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported + // by the proto compiler + (*variables)["deprecation"] = descriptor->options().deprecated() + ? "@java.lang.Deprecated " : ""; + (*variables)["on_changed"] = + HasDescriptorMethods(descriptor->containing_type()) ? "onChanged();" : ""; + + // For singular messages and builders, one bit is used for the hasField bit. + (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex); + + (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex); + (*variables)["set_has_field_bit_builder"] = GenerateSetBit(builderBitIndex); + (*variables)["clear_has_field_bit_builder"] = + GenerateClearBit(builderBitIndex); + + // For repated builders, one bit is used for whether the array is immutable. + (*variables)["get_mutable_bit_builder"] = GenerateGetBit(builderBitIndex); + (*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex); + (*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex); + + (*variables)["get_has_field_bit_from_local"] = + GenerateGetBitFromLocal(builderBitIndex); + (*variables)["set_has_field_bit_to_local"] = + GenerateSetBitToLocal(messageBitIndex); } } // namespace @@ -68,68 +95,244 @@ void SetMessageVariables(const FieldDescriptor* descriptor, // =================================================================== MessageFieldGenerator:: -MessageFieldGenerator(const FieldDescriptor* descriptor) - : descriptor_(descriptor) { - SetMessageVariables(descriptor, &variables_); +MessageFieldGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, + int builderBitIndex) + : descriptor_(descriptor), messageBitIndex_(messageBitIndex), + builderBitIndex_(builderBitIndex) { + SetMessageVariables(descriptor, messageBitIndex, builderBitIndex, + &variables_); } MessageFieldGenerator::~MessageFieldGenerator() {} +int MessageFieldGenerator::GetNumBitsForMessage() const { + return 1; +} + +int MessageFieldGenerator::GetNumBitsForBuilder() const { + return 1; +} + +void MessageFieldGenerator:: +GenerateInterfaceMembers(io::Printer* printer) const { + // TODO(jonp): In the future, consider having a method specific to the + // interface so that builders can choose dynamically to either return a + // message or a nested builder, so that asking for the interface doesn't + // cause a message to ever be built. + printer->Print(variables_, + "$deprecation$boolean has$capitalized_name$();\n" + "$deprecation$$type$ get$capitalized_name$();\n"); + + if (HasNestedBuilders(descriptor_->containing_type())) { + printer->Print(variables_, + "$deprecation$$type$OrBuilder get$capitalized_name$OrBuilder();\n"); + } +} + void MessageFieldGenerator:: GenerateMembers(io::Printer* printer) const { printer->Print(variables_, - "private boolean has$capitalized_name$;\n" "private $type$ $name$_;\n" - "public boolean has$capitalized_name$() { return has$capitalized_name$; }\n" - "public $type$ get$capitalized_name$() { return $name$_; }\n"); + "$deprecation$public boolean has$capitalized_name$() {\n" + " return $get_has_field_bit_message$;\n" + "}\n" + "$deprecation$public $type$ get$capitalized_name$() {\n" + " return $name$_;\n" + "}\n"); + + if (HasNestedBuilders(descriptor_->containing_type())) { + printer->Print(variables_, + "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder() {\n" + " return $name$_;\n" + "}\n"); + } +} + +void MessageFieldGenerator::PrintNestedBuilderCondition( + io::Printer* printer, + const char* regular_case, + const char* nested_builder_case) const { + if (HasNestedBuilders(descriptor_->containing_type())) { + printer->Print(variables_, "if ($name$Builder_ == null) {\n"); + printer->Indent(); + printer->Print(variables_, regular_case); + printer->Outdent(); + printer->Print("} else {\n"); + printer->Indent(); + printer->Print(variables_, nested_builder_case); + printer->Outdent(); + printer->Print("}\n"); + } else { + printer->Print(variables_, regular_case); + } +} + +void MessageFieldGenerator::PrintNestedBuilderFunction( + io::Printer* printer, + const char* method_prototype, + const char* regular_case, + const char* nested_builder_case, + const char* trailing_code) const { + printer->Print(variables_, method_prototype); + printer->Print(" {\n"); + printer->Indent(); + PrintNestedBuilderCondition(printer, regular_case, nested_builder_case); + if (trailing_code != NULL) { + printer->Print(variables_, trailing_code); + } + printer->Outdent(); + printer->Print("}\n"); } void MessageFieldGenerator:: GenerateBuilderMembers(io::Printer* printer) const { + // When using nested-builders, the code initially works just like the + // non-nested builder case. It only creates a nested builder lazily on + // demand and then forever delegates to it after creation. + printer->Print(variables_, - "public boolean has$capitalized_name$() {\n" - " return result.has$capitalized_name$();\n" - "}\n" - "public $type$ get$capitalized_name$() {\n" - " return result.get$capitalized_name$();\n" - "}\n" - "public Builder set$capitalized_name$($type$ value) {\n" - " if (value == null) {\n" - " throw new NullPointerException();\n" - " }\n" - " result.has$capitalized_name$ = true;\n" - " result.$name$_ = value;\n" - " return this;\n" - "}\n" - "public Builder set$capitalized_name$($type$.Builder builderForValue) {\n" - " result.has$capitalized_name$ = true;\n" - " result.$name$_ = builderForValue.build();\n" - " return this;\n" + // Used when the builder is null. + "private $type$ $name$_ = $type$.getDefaultInstance();\n"); + + if (HasNestedBuilders(descriptor_->containing_type())) { + printer->Print(variables_, + // If this builder is non-null, it is used and the other fields are + // ignored. + "private com.google.protobuf.SingleFieldBuilder<\n" + " $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;" + "\n"); + } + + // The comments above the methods below are based on a hypothetical + // field of type "Field" called "Field". + + // boolean hasField() + printer->Print(variables_, + "$deprecation$public boolean has$capitalized_name$() {\n" + " return $get_has_field_bit_builder$;\n" + "}\n"); + + // Field getField() + PrintNestedBuilderFunction(printer, + "$deprecation$public $type$ get$capitalized_name$()", + + "return $name$_;\n", + + "return $name$Builder_.getMessage();\n", + + NULL); + + // Field.Builder setField(Field value) + PrintNestedBuilderFunction(printer, + "$deprecation$public Builder set$capitalized_name$($type$ value)", + + "if (value == null) {\n" + " throw new NullPointerException();\n" "}\n" - "public Builder merge$capitalized_name$($type$ value) {\n" - " if (result.has$capitalized_name$() &&\n" - " result.$name$_ != $type$.getDefaultInstance()) {\n" - " result.$name$_ =\n" - " $type$.newBuilder(result.$name$_).mergeFrom(value).buildPartial();\n" - " } else {\n" - " result.$name$_ = value;\n" - " }\n" - " result.has$capitalized_name$ = true;\n" - " return this;\n" + "$name$_ = value;\n" + "$on_changed$\n", + + "$name$Builder_.setMessage(value);\n", + + "$set_has_field_bit_builder$;\n" + "return this;\n"); + + // Field.Builder setField(Field.Builder builderForValue) + PrintNestedBuilderFunction(printer, + "$deprecation$public Builder set$capitalized_name$(\n" + " $type$.Builder builderForValue)", + + "$name$_ = builderForValue.build();\n" + "$on_changed$\n", + + "$name$Builder_.setMessage(builderForValue.build());\n", + + "$set_has_field_bit_builder$;\n" + "return this;\n"); + + // Field.Builder mergeField(Field value) + PrintNestedBuilderFunction(printer, + "$deprecation$public Builder merge$capitalized_name$($type$ value)", + + "if ($get_has_field_bit_builder$ &&\n" + " $name$_ != $type$.getDefaultInstance()) {\n" + " $name$_ =\n" + " $type$.newBuilder($name$_).mergeFrom(value).buildPartial();\n" + "} else {\n" + " $name$_ = value;\n" "}\n" - "public Builder clear$capitalized_name$() {\n" - " result.has$capitalized_name$ = false;\n" - " result.$name$_ = $type$.getDefaultInstance();\n" - " return this;\n" - "}\n"); + "$on_changed$\n", + + "$name$Builder_.mergeFrom(value);\n", + + "$set_has_field_bit_builder$;\n" + "return this;\n"); + + // Field.Builder clearField() + PrintNestedBuilderFunction(printer, + "$deprecation$public Builder clear$capitalized_name$()", + + "$name$_ = $type$.getDefaultInstance();\n" + "$on_changed$\n", + + "$name$Builder_.clear();\n", + + "$clear_has_field_bit_builder$;\n" + "return this;\n"); + + if (HasNestedBuilders(descriptor_->containing_type())) { + printer->Print(variables_, + "$deprecation$public $type$.Builder get$capitalized_name$Builder() {\n" + " $set_has_field_bit_builder$;\n" + " $on_changed$\n" + " return get$capitalized_name$FieldBuilder().getBuilder();\n" + "}\n" + "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder() {\n" + " if ($name$Builder_ != null) {\n" + " return $name$Builder_.getMessageOrBuilder();\n" + " } else {\n" + " return $name$_;\n" + " }\n" + "}\n" + "private com.google.protobuf.SingleFieldBuilder<\n" + " $type$, $type$.Builder, $type$OrBuilder> \n" + " get$capitalized_name$FieldBuilder() {\n" + " if ($name$Builder_ == null) {\n" + " $name$Builder_ = new com.google.protobuf.SingleFieldBuilder<\n" + " $type$, $type$.Builder, $type$OrBuilder>(\n" + " $name$_,\n" + " getParentForChildren(),\n" + " isClean());\n" + " $name$_ = null;\n" + " }\n" + " return $name$Builder_;\n" + "}\n"); + } } void MessageFieldGenerator:: +GenerateFieldBuilderInitializationCode(io::Printer* printer) const { + printer->Print(variables_, + "get$capitalized_name$FieldBuilder();\n"); +} + + +void MessageFieldGenerator:: GenerateInitializationCode(io::Printer* printer) const { printer->Print(variables_, "$name$_ = $type$.getDefaultInstance();\n"); } void MessageFieldGenerator:: +GenerateBuilderClearCode(io::Printer* printer) const { + PrintNestedBuilderCondition(printer, + "$name$_ = $type$.getDefaultInstance();\n", + + "$name$Builder_.clear();\n"); + printer->Print(variables_, "$clear_has_field_bit_builder$;\n"); +} + +void MessageFieldGenerator:: GenerateMergingCode(io::Printer* printer) const { printer->Print(variables_, "if (other.has$capitalized_name$()) {\n" @@ -139,7 +342,16 @@ GenerateMergingCode(io::Printer* printer) const { void MessageFieldGenerator:: GenerateBuildingCode(io::Printer* printer) const { - // Nothing to do for singular fields. + + printer->Print(variables_, + "if ($get_has_field_bit_from_local$) {\n" + " $set_has_field_bit_to_local$;\n" + "}\n"); + + PrintNestedBuilderCondition(printer, + "result.$name$_ = $name$_;\n", + + "result.$name$_ = $name$Builder_.build();\n"); } void MessageFieldGenerator:: @@ -165,20 +377,34 @@ GenerateParsingCode(io::Printer* printer) const { void MessageFieldGenerator:: GenerateSerializationCode(io::Printer* printer) const { printer->Print(variables_, - "if (has$capitalized_name$()) {\n" - " output.write$group_or_message$($number$, get$capitalized_name$());\n" + "if ($get_has_field_bit_message$) {\n" + " output.write$group_or_message$($number$, $name$_);\n" "}\n"); } void MessageFieldGenerator:: GenerateSerializedSizeCode(io::Printer* printer) const { printer->Print(variables_, - "if (has$capitalized_name$()) {\n" + "if ($get_has_field_bit_message$) {\n" " size += com.google.protobuf.CodedOutputStream\n" - " .compute$group_or_message$Size($number$, get$capitalized_name$());\n" + " .compute$group_or_message$Size($number$, $name$_);\n" "}\n"); } +void MessageFieldGenerator:: +GenerateEqualsCode(io::Printer* printer) const { + printer->Print(variables_, + "result = result && get$capitalized_name$()\n" + " .equals(other.get$capitalized_name$());\n"); +} + +void MessageFieldGenerator:: +GenerateHashCode(io::Printer* printer) const { + printer->Print(variables_, + "hash = (37 * hash) + $constant_name$;\n" + "hash = (53 * hash) + get$capitalized_name$().hashCode();\n"); +} + string MessageFieldGenerator::GetBoxedType() const { return ClassName(descriptor_->message_type()); } @@ -186,109 +412,416 @@ string MessageFieldGenerator::GetBoxedType() const { // =================================================================== RepeatedMessageFieldGenerator:: -RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor) - : descriptor_(descriptor) { - SetMessageVariables(descriptor, &variables_); +RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, + int builderBitIndex) + : descriptor_(descriptor), messageBitIndex_(messageBitIndex), + builderBitIndex_(builderBitIndex) { + SetMessageVariables(descriptor, messageBitIndex, builderBitIndex, + &variables_); } RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {} +int RepeatedMessageFieldGenerator::GetNumBitsForMessage() const { + return 0; +} + +int RepeatedMessageFieldGenerator::GetNumBitsForBuilder() const { + return 1; +} + +void RepeatedMessageFieldGenerator:: +GenerateInterfaceMembers(io::Printer* printer) const { + // TODO(jonp): In the future, consider having methods specific to the + // interface so that builders can choose dynamically to either return a + // message or a nested builder, so that asking for the interface doesn't + // cause a message to ever be built. + printer->Print(variables_, + "$deprecation$java.util.List<$type$> \n" + " get$capitalized_name$List();\n" + "$deprecation$$type$ get$capitalized_name$(int index);\n" + "$deprecation$int get$capitalized_name$Count();\n"); + if (HasNestedBuilders(descriptor_->containing_type())) { + printer->Print(variables_, + "$deprecation$java.util.List<? extends $type$OrBuilder> \n" + " get$capitalized_name$OrBuilderList();\n" + "$deprecation$$type$OrBuilder get$capitalized_name$OrBuilder(\n" + " int index);\n"); + } +} + void RepeatedMessageFieldGenerator:: GenerateMembers(io::Printer* printer) const { printer->Print(variables_, - "private java.util.List<$type$> $name$_ =\n" - " java.util.Collections.emptyList();\n" - "public java.util.List<$type$> get$capitalized_name$List() {\n" + "private java.util.List<$type$> $name$_;\n" + "$deprecation$public java.util.List<$type$> get$capitalized_name$List() {\n" " return $name$_;\n" // note: unmodifiable list "}\n" - "public int get$capitalized_name$Count() { return $name$_.size(); }\n" - "public $type$ get$capitalized_name$(int index) {\n" + "$deprecation$public java.util.List<? extends $type$OrBuilder> \n" + " get$capitalized_name$OrBuilderList() {\n" + " return $name$_;\n" + "}\n" + "$deprecation$public int get$capitalized_name$Count() {\n" + " return $name$_.size();\n" + "}\n" + "$deprecation$public $type$ get$capitalized_name$(int index) {\n" + " return $name$_.get(index);\n" + "}\n" + "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder(\n" + " int index) {\n" " return $name$_.get(index);\n" "}\n"); + +} + +void RepeatedMessageFieldGenerator::PrintNestedBuilderCondition( + io::Printer* printer, + const char* regular_case, + const char* nested_builder_case) const { + if (HasNestedBuilders(descriptor_->containing_type())) { + printer->Print(variables_, "if ($name$Builder_ == null) {\n"); + printer->Indent(); + printer->Print(variables_, regular_case); + printer->Outdent(); + printer->Print("} else {\n"); + printer->Indent(); + printer->Print(variables_, nested_builder_case); + printer->Outdent(); + printer->Print("}\n"); + } else { + printer->Print(variables_, regular_case); + } +} + +void RepeatedMessageFieldGenerator::PrintNestedBuilderFunction( + io::Printer* printer, + const char* method_prototype, + const char* regular_case, + const char* nested_builder_case, + const char* trailing_code) const { + printer->Print(variables_, method_prototype); + printer->Print(" {\n"); + printer->Indent(); + PrintNestedBuilderCondition(printer, regular_case, nested_builder_case); + if (trailing_code != NULL) { + printer->Print(variables_, trailing_code); + } + printer->Outdent(); + printer->Print("}\n"); } void RepeatedMessageFieldGenerator:: GenerateBuilderMembers(io::Printer* printer) const { + // When using nested-builders, the code initially works just like the + // non-nested builder case. It only creates a nested builder lazily on + // demand and then forever delegates to it after creation. + printer->Print(variables_, - // Note: We return an unmodifiable list because otherwise the caller - // could hold on to the returned list and modify it after the message - // has been built, thus mutating the message which is supposed to be - // immutable. - "public java.util.List<$type$> get$capitalized_name$List() {\n" - " return java.util.Collections.unmodifiableList(result.$name$_);\n" - "}\n" - "public int get$capitalized_name$Count() {\n" - " return result.get$capitalized_name$Count();\n" - "}\n" - "public $type$ get$capitalized_name$(int index) {\n" - " return result.get$capitalized_name$(index);\n" - "}\n" - "public Builder set$capitalized_name$(int index, $type$ value) {\n" - " if (value == null) {\n" - " throw new NullPointerException();\n" - " }\n" - " result.$name$_.set(index, value);\n" - " return this;\n" - "}\n" - "public Builder set$capitalized_name$(int index, " - "$type$.Builder builderForValue) {\n" - " result.$name$_.set(index, builderForValue.build());\n" - " return this;\n" + // Used when the builder is null. + // One field is the list and the other field keeps track of whether the + // list is immutable. If it's immutable, the invariant is that it must + // either an instance of Collections.emptyList() or it's an ArrayList + // wrapped in a Collections.unmodifiableList() wrapper and nobody else has + // a refererence to the underlying ArrayList. This invariant allows us to + // share instances of lists between protocol buffers avoiding expensive + // memory allocations. Note, immutable is a strong guarantee here -- not + // just that the list cannot be modified via the reference but that the + // list can never be modified. + "private java.util.List<$type$> $name$_ =\n" + " java.util.Collections.emptyList();\n" + + "private void ensure$capitalized_name$IsMutable() {\n" + " if (!$get_mutable_bit_builder$) {\n" + " $name$_ = new java.util.ArrayList<$type$>($name$_);\n" + " $set_mutable_bit_builder$;\n" + " }\n" "}\n" - "public Builder add$capitalized_name$($type$ value) {\n" - " if (value == null) {\n" - " throw new NullPointerException();\n" - " }\n" - " if (result.$name$_.isEmpty()) {\n" - " result.$name$_ = new java.util.ArrayList<$type$>();\n" - " }\n" - " result.$name$_.add(value);\n" - " return this;\n" + "\n"); + + if (HasNestedBuilders(descriptor_->containing_type())) { + printer->Print(variables_, + // If this builder is non-null, it is used and the other fields are + // ignored. + "private com.google.protobuf.RepeatedFieldBuilder<\n" + " $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;\n" + "\n"); + } + + // The comments above the methods below are based on a hypothetical + // repeated field of type "Field" called "RepeatedField". + + // List<Field> getRepeatedFieldList() + PrintNestedBuilderFunction(printer, + "$deprecation$public java.util.List<$type$> get$capitalized_name$List()", + + "return java.util.Collections.unmodifiableList($name$_);\n", + "return $name$Builder_.getMessageList();\n", + + NULL); + + // int getRepeatedFieldCount() + PrintNestedBuilderFunction(printer, + "$deprecation$public int get$capitalized_name$Count()", + + "return $name$_.size();\n", + "return $name$Builder_.getCount();\n", + + NULL); + + // Field getRepeatedField(int index) + PrintNestedBuilderFunction(printer, + "$deprecation$public $type$ get$capitalized_name$(int index)", + + "return $name$_.get(index);\n", + + "return $name$Builder_.getMessage(index);\n", + + NULL); + + // Builder setRepeatedField(int index, Field value) + PrintNestedBuilderFunction(printer, + "$deprecation$public Builder set$capitalized_name$(\n" + " int index, $type$ value)", + "if (value == null) {\n" + " throw new NullPointerException();\n" "}\n" - "public Builder add$capitalized_name$($type$.Builder builderForValue) {\n" - " if (result.$name$_.isEmpty()) {\n" - " result.$name$_ = new java.util.ArrayList<$type$>();\n" - " }\n" - " result.$name$_.add(builderForValue.build());\n" - " return this;\n" + "ensure$capitalized_name$IsMutable();\n" + "$name$_.set(index, value);\n" + "$on_changed$\n", + "$name$Builder_.setMessage(index, value);\n", + "return this;\n"); + + // Builder setRepeatedField(int index, Field.Builder builderForValue) + PrintNestedBuilderFunction(printer, + "$deprecation$public Builder set$capitalized_name$(\n" + " int index, $type$.Builder builderForValue)", + + "ensure$capitalized_name$IsMutable();\n" + "$name$_.set(index, builderForValue.build());\n" + "$on_changed$\n", + + "$name$Builder_.setMessage(index, builderForValue.build());\n", + + "return this;\n"); + + // Builder addRepeatedField(Field value) + PrintNestedBuilderFunction(printer, + "$deprecation$public Builder add$capitalized_name$($type$ value)", + + "if (value == null) {\n" + " throw new NullPointerException();\n" "}\n" - "public Builder addAll$capitalized_name$(\n" - " java.lang.Iterable<? extends $type$> values) {\n" - " if (result.$name$_.isEmpty()) {\n" - " result.$name$_ = new java.util.ArrayList<$type$>();\n" - " }\n" - " super.addAll(values, result.$name$_);\n" - " return this;\n" + "ensure$capitalized_name$IsMutable();\n" + "$name$_.add(value);\n" + + "$on_changed$\n", + + "$name$Builder_.addMessage(value);\n", + + "return this;\n"); + + // Builder addRepeatedField(int index, Field value) + PrintNestedBuilderFunction(printer, + "$deprecation$public Builder add$capitalized_name$(\n" + " int index, $type$ value)", + + "if (value == null) {\n" + " throw new NullPointerException();\n" "}\n" - "public Builder clear$capitalized_name$() {\n" - " result.$name$_ = java.util.Collections.emptyList();\n" - " return this;\n" - "}\n"); + "ensure$capitalized_name$IsMutable();\n" + "$name$_.add(index, value);\n" + "$on_changed$\n", + + "$name$Builder_.addMessage(index, value);\n", + + "return this;\n"); + + // Builder addRepeatedField(Field.Builder builderForValue) + PrintNestedBuilderFunction(printer, + "$deprecation$public Builder add$capitalized_name$(\n" + " $type$.Builder builderForValue)", + + "ensure$capitalized_name$IsMutable();\n" + "$name$_.add(builderForValue.build());\n" + "$on_changed$\n", + + "$name$Builder_.addMessage(builderForValue.build());\n", + + "return this;\n"); + + // Builder addRepeatedField(int index, Field.Builder builderForValue) + PrintNestedBuilderFunction(printer, + "$deprecation$public Builder add$capitalized_name$(\n" + " int index, $type$.Builder builderForValue)", + + "ensure$capitalized_name$IsMutable();\n" + "$name$_.add(index, builderForValue.build());\n" + "$on_changed$\n", + + "$name$Builder_.addMessage(index, builderForValue.build());\n", + + "return this;\n"); + + // Builder addAllRepeatedField(Iterable<Field> values) + PrintNestedBuilderFunction(printer, + "$deprecation$public Builder addAll$capitalized_name$(\n" + " java.lang.Iterable<? extends $type$> values)", + + "ensure$capitalized_name$IsMutable();\n" + "super.addAll(values, $name$_);\n" + "$on_changed$\n", + + "$name$Builder_.addAllMessages(values);\n", + + "return this;\n"); + + // Builder clearAllRepeatedField() + PrintNestedBuilderFunction(printer, + "$deprecation$public Builder clear$capitalized_name$()", + + "$name$_ = java.util.Collections.emptyList();\n" + "$clear_mutable_bit_builder$;\n" + "$on_changed$\n", + + "$name$Builder_.clear();\n", + + "return this;\n"); + + // Builder removeRepeatedField(int index) + PrintNestedBuilderFunction(printer, + "$deprecation$public Builder remove$capitalized_name$(int index)", + + "ensure$capitalized_name$IsMutable();\n" + "$name$_.remove(index);\n" + "$on_changed$\n", + + "$name$Builder_.remove(index);\n", + + "return this;\n"); + + if (HasNestedBuilders(descriptor_->containing_type())) { + printer->Print(variables_, + "$deprecation$public $type$.Builder get$capitalized_name$Builder(\n" + " int index) {\n" + " return get$capitalized_name$FieldBuilder().getBuilder(index);\n" + "}\n" + + "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder(\n" + " int index) {\n" + " if ($name$Builder_ == null) {\n" + " return $name$_.get(index);" + " } else {\n" + " return $name$Builder_.getMessageOrBuilder(index);\n" + " }\n" + "}\n" + + "$deprecation$public java.util.List<? extends $type$OrBuilder> \n" + " get$capitalized_name$OrBuilderList() {\n" + " if ($name$Builder_ != null) {\n" + " return $name$Builder_.getMessageOrBuilderList();\n" + " } else {\n" + " return java.util.Collections.unmodifiableList($name$_);\n" + " }\n" + "}\n" + + "$deprecation$public $type$.Builder add$capitalized_name$Builder() {\n" + " return get$capitalized_name$FieldBuilder().addBuilder(\n" + " $type$.getDefaultInstance());\n" + "}\n" + "$deprecation$public $type$.Builder add$capitalized_name$Builder(\n" + " int index) {\n" + " return get$capitalized_name$FieldBuilder().addBuilder(\n" + " index, $type$.getDefaultInstance());\n" + "}\n" + "$deprecation$public java.util.List<$type$.Builder> \n" + " get$capitalized_name$BuilderList() {\n" + " return get$capitalized_name$FieldBuilder().getBuilderList();\n" + "}\n" + "private com.google.protobuf.RepeatedFieldBuilder<\n" + " $type$, $type$.Builder, $type$OrBuilder> \n" + " get$capitalized_name$FieldBuilder() {\n" + " if ($name$Builder_ == null) {\n" + " $name$Builder_ = new com.google.protobuf.RepeatedFieldBuilder<\n" + " $type$, $type$.Builder, $type$OrBuilder>(\n" + " $name$_,\n" + " $get_mutable_bit_builder$,\n" + " getParentForChildren(),\n" + " isClean());\n" + " $name$_ = null;\n" + " }\n" + " return $name$Builder_;\n" + "}\n"); + } +} + +void RepeatedMessageFieldGenerator:: +GenerateFieldBuilderInitializationCode(io::Printer* printer) const { + printer->Print(variables_, + "get$capitalized_name$FieldBuilder();\n"); } void RepeatedMessageFieldGenerator:: GenerateInitializationCode(io::Printer* printer) const { - // Initialized inline. + printer->Print(variables_, "$name$_ = java.util.Collections.emptyList();\n"); +} + +void RepeatedMessageFieldGenerator:: +GenerateBuilderClearCode(io::Printer* printer) const { + PrintNestedBuilderCondition(printer, + "$name$_ = java.util.Collections.emptyList();\n" + "$clear_mutable_bit_builder$;\n", + + "$name$Builder_.clear();\n"); } void RepeatedMessageFieldGenerator:: GenerateMergingCode(io::Printer* printer) const { - printer->Print(variables_, + // The code below does two optimizations (non-nested builder case): + // 1. If the other list is empty, there's nothing to do. This ensures we + // don't allocate a new array if we already have an immutable one. + // 2. If the other list is non-empty and our current list is empty, we can + // reuse the other list which is guaranteed to be immutable. + PrintNestedBuilderCondition(printer, "if (!other.$name$_.isEmpty()) {\n" - " if (result.$name$_.isEmpty()) {\n" - " result.$name$_ = new java.util.ArrayList<$type$>();\n" + " if ($name$_.isEmpty()) {\n" + " $name$_ = other.$name$_;\n" + " $clear_mutable_bit_builder$;\n" + " } else {\n" + " ensure$capitalized_name$IsMutable();\n" + " $name$_.addAll(other.$name$_);\n" + " }\n" + " $on_changed$\n" + "}\n", + + "if (!other.$name$_.isEmpty()) {\n" + " if ($name$Builder_.isEmpty()) {\n" + " $name$Builder_.dispose();\n" + " $name$Builder_ = null;\n" + " $name$_ = other.$name$_;\n" + " $clear_mutable_bit_builder$;\n" + " $name$Builder_ = \n" + " com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?\n" + " get$capitalized_name$FieldBuilder() : null;\n" + " } else {\n" + " $name$Builder_.addAllMessages(other.$name$_);\n" " }\n" - " result.$name$_.addAll(other.$name$_);\n" "}\n"); } void RepeatedMessageFieldGenerator:: GenerateBuildingCode(io::Printer* printer) const { - printer->Print(variables_, - "if (result.$name$_ != java.util.Collections.EMPTY_LIST) {\n" - " result.$name$_ =\n" - " java.util.Collections.unmodifiableList(result.$name$_);\n" - "}\n"); + // The code below (non-nested builder case) ensures that the result has an + // immutable list. If our list is immutable, we can just reuse it. If not, + // we make it immutable. + PrintNestedBuilderCondition(printer, + "if ($get_mutable_bit_builder$) {\n" + " $name$_ = java.util.Collections.unmodifiableList($name$_);\n" + " $clear_mutable_bit_builder$;\n" + "}\n" + "result.$name$_ = $name$_;\n", + + "result.$name$_ = $name$Builder_.build();\n"); } void RepeatedMessageFieldGenerator:: @@ -311,17 +844,33 @@ GenerateParsingCode(io::Printer* printer) const { void RepeatedMessageFieldGenerator:: GenerateSerializationCode(io::Printer* printer) const { printer->Print(variables_, - "for ($type$ element : get$capitalized_name$List()) {\n" - " output.write$group_or_message$($number$, element);\n" + "for (int i = 0; i < $name$_.size(); i++) {\n" + " output.write$group_or_message$($number$, $name$_.get(i));\n" "}\n"); } void RepeatedMessageFieldGenerator:: GenerateSerializedSizeCode(io::Printer* printer) const { printer->Print(variables_, - "for ($type$ element : get$capitalized_name$List()) {\n" + "for (int i = 0; i < $name$_.size(); i++) {\n" " size += com.google.protobuf.CodedOutputStream\n" - " .compute$group_or_message$Size($number$, element);\n" + " .compute$group_or_message$Size($number$, $name$_.get(i));\n" + "}\n"); +} + +void RepeatedMessageFieldGenerator:: +GenerateEqualsCode(io::Printer* printer) const { + printer->Print(variables_, + "result = result && get$capitalized_name$List()\n" + " .equals(other.get$capitalized_name$List());\n"); +} + +void RepeatedMessageFieldGenerator:: +GenerateHashCode(io::Printer* printer) const { + printer->Print(variables_, + "if (get$capitalized_name$Count() > 0) {\n" + " hash = (37 * hash) + $constant_name$;\n" + " hash = (53 * hash) + get$capitalized_name$List().hashCode();\n" "}\n"); } diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_message_field.h b/third_party/protobuf/src/google/protobuf/compiler/java/java_message_field.h index 66bdd88..2efbcd9 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_message_field.h +++ b/third_party/protobuf/src/google/protobuf/compiler/java/java_message_field.h @@ -46,50 +46,84 @@ namespace java { class MessageFieldGenerator : public FieldGenerator { public: - explicit MessageFieldGenerator(const FieldDescriptor* descriptor); + explicit MessageFieldGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, int builderBitIndex); ~MessageFieldGenerator(); // implements FieldGenerator --------------------------------------- + int GetNumBitsForMessage() const; + int GetNumBitsForBuilder() const; + void GenerateInterfaceMembers(io::Printer* printer) const; void GenerateMembers(io::Printer* printer) const; void GenerateBuilderMembers(io::Printer* printer) const; void GenerateInitializationCode(io::Printer* printer) const; + void GenerateBuilderClearCode(io::Printer* printer) const; void GenerateMergingCode(io::Printer* printer) const; void GenerateBuildingCode(io::Printer* printer) const; void GenerateParsingCode(io::Printer* printer) const; void GenerateSerializationCode(io::Printer* printer) const; void GenerateSerializedSizeCode(io::Printer* printer) const; + void GenerateFieldBuilderInitializationCode(io::Printer* printer) const; + void GenerateEqualsCode(io::Printer* printer) const; + void GenerateHashCode(io::Printer* printer) const; string GetBoxedType() const; private: const FieldDescriptor* descriptor_; map<string, string> variables_; + const int messageBitIndex_; + const int builderBitIndex_; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageFieldGenerator); + + void PrintNestedBuilderCondition(io::Printer* printer, + const char* regular_case, const char* nested_builder_case) const; + void PrintNestedBuilderFunction(io::Printer* printer, + const char* method_prototype, const char* regular_case, + const char* nested_builder_case, + const char* trailing_code) const; }; class RepeatedMessageFieldGenerator : public FieldGenerator { public: - explicit RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor); + explicit RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, int builderBitIndex); ~RepeatedMessageFieldGenerator(); // implements FieldGenerator --------------------------------------- + int GetNumBitsForMessage() const; + int GetNumBitsForBuilder() const; + void GenerateInterfaceMembers(io::Printer* printer) const; void GenerateMembers(io::Printer* printer) const; void GenerateBuilderMembers(io::Printer* printer) const; void GenerateInitializationCode(io::Printer* printer) const; + void GenerateBuilderClearCode(io::Printer* printer) const; void GenerateMergingCode(io::Printer* printer) const; void GenerateBuildingCode(io::Printer* printer) const; void GenerateParsingCode(io::Printer* printer) const; void GenerateSerializationCode(io::Printer* printer) const; void GenerateSerializedSizeCode(io::Printer* printer) const; + void GenerateFieldBuilderInitializationCode(io::Printer* printer) const; + void GenerateEqualsCode(io::Printer* printer) const; + void GenerateHashCode(io::Printer* printer) const; string GetBoxedType() const; private: const FieldDescriptor* descriptor_; map<string, string> variables_; + const int messageBitIndex_; + const int builderBitIndex_; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedMessageFieldGenerator); + + void PrintNestedBuilderCondition(io::Printer* printer, + const char* regular_case, const char* nested_builder_case) const; + void PrintNestedBuilderFunction(io::Printer* printer, + const char* method_prototype, const char* regular_case, + const char* nested_builder_case, + const char* trailing_code) const; }; } // namespace java diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_plugin_unittest.cc b/third_party/protobuf/src/google/protobuf/compiler/java/java_plugin_unittest.cc index cfe0188..ccc94c9 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_plugin_unittest.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/java/java_plugin_unittest.cc @@ -56,21 +56,22 @@ class TestGenerator : public CodeGenerator { virtual bool Generate(const FileDescriptor* file, const string& parameter, - OutputDirectory* output_directory, + GeneratorContext* context, string* error) const { - TryInsert("Test.java", "outer_class_scope", output_directory); - TryInsert("Test.java", "class_scope:foo.Bar", output_directory); - TryInsert("Test.java", "class_scope:foo.Bar.Baz", output_directory); - TryInsert("Test.java", "builder_scope:foo.Bar", output_directory); - TryInsert("Test.java", "builder_scope:foo.Bar.Baz", output_directory); - TryInsert("Test.java", "enum_scope:foo.Qux", output_directory); + string filename = "Test.java"; + TryInsert(filename, "outer_class_scope", context); + TryInsert(filename, "class_scope:foo.Bar", context); + TryInsert(filename, "class_scope:foo.Bar.Baz", context); + TryInsert(filename, "builder_scope:foo.Bar", context); + TryInsert(filename, "builder_scope:foo.Bar.Baz", context); + TryInsert(filename, "enum_scope:foo.Qux", context); return true; } void TryInsert(const string& filename, const string& insertion_point, - OutputDirectory* output_directory) const { + GeneratorContext* context) const { scoped_ptr<io::ZeroCopyOutputStream> output( - output_directory->OpenForInsert(filename, insertion_point)); + context->OpenForInsert(filename, insertion_point)); io::Printer printer(output.get(), '$'); printer.Print("// inserted $name$\n", "name", insertion_point); } diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_primitive_field.cc b/third_party/protobuf/src/google/protobuf/compiler/java/java_primitive_field.cc index f6179bf..addb881 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_primitive_field.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/java/java_primitive_field.cc @@ -154,15 +154,24 @@ int FixedSize(FieldDescriptor::Type type) { } void SetPrimitiveVariables(const FieldDescriptor* descriptor, + int messageBitIndex, + int builderBitIndex, map<string, string>* variables) { (*variables)["name"] = UnderscoresToCamelCase(descriptor); (*variables)["capitalized_name"] = UnderscoresToCapitalizedCamelCase(descriptor); + (*variables)["constant_name"] = FieldConstantName(descriptor); (*variables)["number"] = SimpleItoa(descriptor->number()); (*variables)["type"] = PrimitiveTypeName(GetJavaType(descriptor)); (*variables)["boxed_type"] = BoxedPrimitiveTypeName(GetJavaType(descriptor)); + (*variables)["field_type"] = (*variables)["type"]; + (*variables)["field_list_type"] = "java.util.List<" + + (*variables)["boxed_type"] + ">"; + (*variables)["empty_list"] = "java.util.Collections.emptyList();"; (*variables)["default"] = DefaultValue(descriptor); + (*variables)["default_init"] = IsDefaultValueJavaDefault(descriptor) ? + "" : ("= " + DefaultValue(descriptor)); (*variables)["capitalized_type"] = GetCapitalizedType(descriptor); (*variables)["tag"] = SimpleItoa(WireFormat::MakeTag(descriptor)); (*variables)["tag_size"] = SimpleItoa( @@ -175,67 +184,135 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor, } else { (*variables)["null_check"] = ""; } + // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported + // by the proto compiler + (*variables)["deprecation"] = descriptor->options().deprecated() + ? "@java.lang.Deprecated " : ""; int fixed_size = FixedSize(GetType(descriptor)); if (fixed_size != -1) { (*variables)["fixed_size"] = SimpleItoa(fixed_size); } + (*variables)["on_changed"] = + HasDescriptorMethods(descriptor->containing_type()) ? "onChanged();" : ""; + + // For singular messages and builders, one bit is used for the hasField bit. + (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex); + + (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex); + (*variables)["set_has_field_bit_builder"] = GenerateSetBit(builderBitIndex); + (*variables)["clear_has_field_bit_builder"] = + GenerateClearBit(builderBitIndex); + + // For repated builders, one bit is used for whether the array is immutable. + (*variables)["get_mutable_bit_builder"] = GenerateGetBit(builderBitIndex); + (*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex); + (*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex); + + (*variables)["get_has_field_bit_from_local"] = + GenerateGetBitFromLocal(builderBitIndex); + (*variables)["set_has_field_bit_to_local"] = + GenerateSetBitToLocal(messageBitIndex); } + } // namespace // =================================================================== PrimitiveFieldGenerator:: -PrimitiveFieldGenerator(const FieldDescriptor* descriptor) - : descriptor_(descriptor) { - SetPrimitiveVariables(descriptor, &variables_); +PrimitiveFieldGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, + int builderBitIndex) + : descriptor_(descriptor), messageBitIndex_(messageBitIndex), + builderBitIndex_(builderBitIndex) { + SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex, + &variables_); } PrimitiveFieldGenerator::~PrimitiveFieldGenerator() {} +int PrimitiveFieldGenerator::GetNumBitsForMessage() const { + return 1; +} + +int PrimitiveFieldGenerator::GetNumBitsForBuilder() const { + return 1; +} + +void PrimitiveFieldGenerator:: +GenerateInterfaceMembers(io::Printer* printer) const { + printer->Print(variables_, + "$deprecation$boolean has$capitalized_name$();\n" + "$deprecation$$type$ get$capitalized_name$();\n"); +} + void PrimitiveFieldGenerator:: GenerateMembers(io::Printer* printer) const { printer->Print(variables_, - "private boolean has$capitalized_name$;\n" - "private $type$ $name$_ = $default$;\n" - "public boolean has$capitalized_name$() { return has$capitalized_name$; }\n" - "public $type$ get$capitalized_name$() { return $name$_; }\n"); + "private $field_type$ $name$_;\n" + "$deprecation$public boolean has$capitalized_name$() {\n" + " return $get_has_field_bit_message$;\n" + "}\n"); + + printer->Print(variables_, + "$deprecation$public $type$ get$capitalized_name$() {\n" + " return $name$_;\n" + "}\n"); } void PrimitiveFieldGenerator:: GenerateBuilderMembers(io::Printer* printer) const { printer->Print(variables_, - "public boolean has$capitalized_name$() {\n" - " return result.has$capitalized_name$();\n" - "}\n" - "public $type$ get$capitalized_name$() {\n" - " return result.get$capitalized_name$();\n" - "}\n" - "public Builder set$capitalized_name$($type$ value) {\n" + "private $field_type$ $name$_ $default_init$;\n" + "$deprecation$public boolean has$capitalized_name$() {\n" + " return $get_has_field_bit_builder$;\n" + "}\n"); + + printer->Print(variables_, + "$deprecation$public $type$ get$capitalized_name$() {\n" + " return $name$_;\n" + "}\n"); + + printer->Print(variables_, + "$deprecation$public Builder set$capitalized_name$($type$ value) {\n" "$null_check$" - " result.has$capitalized_name$ = true;\n" - " result.$name$_ = value;\n" + " $set_has_field_bit_builder$;\n" + " $name$_ = value;\n" + " $on_changed$\n" " return this;\n" "}\n" - "public Builder clear$capitalized_name$() {\n" - " result.has$capitalized_name$ = false;\n"); + "$deprecation$public Builder clear$capitalized_name$() {\n" + " $clear_has_field_bit_builder$;\n"); JavaType type = GetJavaType(descriptor_); if (type == JAVATYPE_STRING || type == JAVATYPE_BYTES) { // The default value is not a simple literal so we want to avoid executing // it multiple times. Instead, get the default out of the default instance. printer->Print(variables_, - " result.$name$_ = getDefaultInstance().get$capitalized_name$();\n"); + " $name$_ = getDefaultInstance().get$capitalized_name$();\n"); } else { printer->Print(variables_, - " result.$name$_ = $default$;\n"); + " $name$_ = $default$;\n"); } printer->Print(variables_, + " $on_changed$\n" " return this;\n" "}\n"); } void PrimitiveFieldGenerator:: +GenerateFieldBuilderInitializationCode(io::Printer* printer) const { + // noop for primitives +} + +void PrimitiveFieldGenerator:: GenerateInitializationCode(io::Printer* printer) const { - // Initialized inline. + printer->Print(variables_, "$name$_ = $default$;\n"); +} + +void PrimitiveFieldGenerator:: +GenerateBuilderClearCode(io::Printer* printer) const { + printer->Print(variables_, + "$name$_ = $default$;\n" + "$clear_has_field_bit_builder$;\n"); } void PrimitiveFieldGenerator:: @@ -248,32 +325,121 @@ GenerateMergingCode(io::Printer* printer) const { void PrimitiveFieldGenerator:: GenerateBuildingCode(io::Printer* printer) const { - // Nothing to do here for primitive types. + printer->Print(variables_, + "if ($get_has_field_bit_from_local$) {\n" + " $set_has_field_bit_to_local$;\n" + "}\n" + "result.$name$_ = $name$_;\n"); } void PrimitiveFieldGenerator:: GenerateParsingCode(io::Printer* printer) const { printer->Print(variables_, - "set$capitalized_name$(input.read$capitalized_type$());\n"); + "$set_has_field_bit_builder$;\n" + "$name$_ = input.read$capitalized_type$();\n"); } void PrimitiveFieldGenerator:: GenerateSerializationCode(io::Printer* printer) const { printer->Print(variables_, - "if (has$capitalized_name$()) {\n" - " output.write$capitalized_type$($number$, get$capitalized_name$());\n" + "if ($get_has_field_bit_message$) {\n" + " output.write$capitalized_type$($number$, $name$_);\n" "}\n"); } void PrimitiveFieldGenerator:: GenerateSerializedSizeCode(io::Printer* printer) const { printer->Print(variables_, - "if (has$capitalized_name$()) {\n" + "if ($get_has_field_bit_message$) {\n" " size += com.google.protobuf.CodedOutputStream\n" - " .compute$capitalized_type$Size($number$, get$capitalized_name$());\n" + " .compute$capitalized_type$Size($number$, $name$_);\n" "}\n"); } +void PrimitiveFieldGenerator:: +GenerateEqualsCode(io::Printer* printer) const { + switch (GetJavaType(descriptor_)) { + case JAVATYPE_INT: + case JAVATYPE_LONG: + case JAVATYPE_BOOLEAN: + printer->Print(variables_, + "result = result && (get$capitalized_name$()\n" + " == other.get$capitalized_name$());\n"); + break; + + case JAVATYPE_FLOAT: + printer->Print(variables_, + "result = result && (Float.floatToIntBits(get$capitalized_name$())" + " == Float.floatToIntBits(other.get$capitalized_name$()));\n"); + break; + + case JAVATYPE_DOUBLE: + printer->Print(variables_, + "result = result && (Double.doubleToLongBits(get$capitalized_name$())" + " == Double.doubleToLongBits(other.get$capitalized_name$()));\n"); + break; + + case JAVATYPE_STRING: + case JAVATYPE_BYTES: + printer->Print(variables_, + "result = result && get$capitalized_name$()\n" + " .equals(other.get$capitalized_name$());\n"); + break; + + case JAVATYPE_ENUM: + case JAVATYPE_MESSAGE: + default: + GOOGLE_LOG(FATAL) << "Can't get here."; + break; + } +} + +void PrimitiveFieldGenerator:: +GenerateHashCode(io::Printer* printer) const { + printer->Print(variables_, + "hash = (37 * hash) + $constant_name$;\n"); + switch (GetJavaType(descriptor_)) { + case JAVATYPE_INT: + printer->Print(variables_, + "hash = (53 * hash) + get$capitalized_name$();\n"); + break; + + case JAVATYPE_LONG: + printer->Print(variables_, + "hash = (53 * hash) + hashLong(get$capitalized_name$());\n"); + break; + + case JAVATYPE_BOOLEAN: + printer->Print(variables_, + "hash = (53 * hash) + hashBoolean(get$capitalized_name$());\n"); + break; + + case JAVATYPE_FLOAT: + printer->Print(variables_, + "hash = (53 * hash) + Float.floatToIntBits(\n" + " get$capitalized_name$());\n"); + break; + + case JAVATYPE_DOUBLE: + printer->Print(variables_, + "hash = (53 * hash) + hashLong(\n" + " Double.doubleToLongBits(get$capitalized_name$()));\n"); + break; + + case JAVATYPE_STRING: + case JAVATYPE_BYTES: + printer->Print(variables_, + "hash = (53 * hash) + get$capitalized_name$().hashCode();\n"); + break; + + case JAVATYPE_ENUM: + case JAVATYPE_MESSAGE: + default: + GOOGLE_LOG(FATAL) << "Can't get here."; + break; + } +} + string PrimitiveFieldGenerator::GetBoxedType() const { return BoxedPrimitiveTypeName(GetJavaType(descriptor_)); } @@ -281,23 +447,46 @@ string PrimitiveFieldGenerator::GetBoxedType() const { // =================================================================== RepeatedPrimitiveFieldGenerator:: -RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor) - : descriptor_(descriptor) { - SetPrimitiveVariables(descriptor, &variables_); +RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, + int builderBitIndex) + : descriptor_(descriptor), messageBitIndex_(messageBitIndex), + builderBitIndex_(builderBitIndex) { + SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex, + &variables_); } RepeatedPrimitiveFieldGenerator::~RepeatedPrimitiveFieldGenerator() {} +int RepeatedPrimitiveFieldGenerator::GetNumBitsForMessage() const { + return 0; +} + +int RepeatedPrimitiveFieldGenerator::GetNumBitsForBuilder() const { + return 1; +} + +void RepeatedPrimitiveFieldGenerator:: +GenerateInterfaceMembers(io::Printer* printer) const { + printer->Print(variables_, + "$deprecation$java.util.List<$boxed_type$> get$capitalized_name$List();\n" + "$deprecation$int get$capitalized_name$Count();\n" + "$deprecation$$type$ get$capitalized_name$(int index);\n"); +} + + void RepeatedPrimitiveFieldGenerator:: GenerateMembers(io::Printer* printer) const { printer->Print(variables_, - "private java.util.List<$boxed_type$> $name$_ =\n" - " java.util.Collections.emptyList();\n" - "public java.util.List<$boxed_type$> get$capitalized_name$List() {\n" + "private $field_list_type$ $name$_;\n" + "$deprecation$public java.util.List<$boxed_type$>\n" + " get$capitalized_name$List() {\n" " return $name$_;\n" // note: unmodifiable list "}\n" - "public int get$capitalized_name$Count() { return $name$_.size(); }\n" - "public $type$ get$capitalized_name$(int index) {\n" + "$deprecation$public int get$capitalized_name$Count() {\n" + " return $name$_.size();\n" + "}\n" + "$deprecation$public $type$ get$capitalized_name$(int index) {\n" " return $name$_.get(index);\n" "}\n"); @@ -310,76 +499,125 @@ GenerateMembers(io::Printer* printer) const { void RepeatedPrimitiveFieldGenerator:: GenerateBuilderMembers(io::Printer* printer) const { + // One field is the list and the bit field keeps track of whether the + // list is immutable. If it's immutable, the invariant is that it must + // either an instance of Collections.emptyList() or it's an ArrayList + // wrapped in a Collections.unmodifiableList() wrapper and nobody else has + // a refererence to the underlying ArrayList. This invariant allows us to + // share instances of lists between protocol buffers avoiding expensive + // memory allocations. Note, immutable is a strong guarantee here -- not + // just that the list cannot be modified via the reference but that the + // list can never be modified. + printer->Print(variables_, + "private $field_list_type$ $name$_ = $empty_list$;\n"); + printer->Print(variables_, + "private void ensure$capitalized_name$IsMutable() {\n" + " if (!$get_mutable_bit_builder$) {\n" + " $name$_ = new java.util.ArrayList<$boxed_type$>($name$_);\n" + " $set_mutable_bit_builder$;\n" + " }\n" + "}\n"); + // Note: We return an unmodifiable list because otherwise the caller // could hold on to the returned list and modify it after the message // has been built, thus mutating the message which is supposed to be // immutable. - "public java.util.List<$boxed_type$> get$capitalized_name$List() {\n" - " return java.util.Collections.unmodifiableList(result.$name$_);\n" + printer->Print(variables_, + "$deprecation$public java.util.List<$boxed_type$>\n" + " get$capitalized_name$List() {\n" + " return java.util.Collections.unmodifiableList($name$_);\n" "}\n" - "public int get$capitalized_name$Count() {\n" - " return result.get$capitalized_name$Count();\n" + "$deprecation$public int get$capitalized_name$Count() {\n" + " return $name$_.size();\n" "}\n" - "public $type$ get$capitalized_name$(int index) {\n" - " return result.get$capitalized_name$(index);\n" + "$deprecation$public $type$ get$capitalized_name$(int index) {\n" + " return $name$_.get(index);\n" "}\n" - "public Builder set$capitalized_name$(int index, $type$ value) {\n" + "$deprecation$public Builder set$capitalized_name$(\n" + " int index, $type$ value) {\n" "$null_check$" - " result.$name$_.set(index, value);\n" + " ensure$capitalized_name$IsMutable();\n" + " $name$_.set(index, value);\n" + " $on_changed$\n" " return this;\n" "}\n" - "public Builder add$capitalized_name$($type$ value) {\n" + "$deprecation$public Builder add$capitalized_name$($type$ value) {\n" "$null_check$" - " if (result.$name$_.isEmpty()) {\n" - " result.$name$_ = new java.util.ArrayList<$boxed_type$>();\n" - " }\n" - " result.$name$_.add(value);\n" + " ensure$capitalized_name$IsMutable();\n" + " $name$_.add(value);\n" + " $on_changed$\n" " return this;\n" "}\n" - "public Builder addAll$capitalized_name$(\n" + "$deprecation$public Builder addAll$capitalized_name$(\n" " java.lang.Iterable<? extends $boxed_type$> values) {\n" - " if (result.$name$_.isEmpty()) {\n" - " result.$name$_ = new java.util.ArrayList<$boxed_type$>();\n" - " }\n" - " super.addAll(values, result.$name$_);\n" + " ensure$capitalized_name$IsMutable();\n" + " super.addAll(values, $name$_);\n" + " $on_changed$\n" " return this;\n" "}\n" - "public Builder clear$capitalized_name$() {\n" - " result.$name$_ = java.util.Collections.emptyList();\n" + "$deprecation$public Builder clear$capitalized_name$() {\n" + " $name$_ = $empty_list$;\n" + " $clear_mutable_bit_builder$;\n" + " $on_changed$\n" " return this;\n" "}\n"); } void RepeatedPrimitiveFieldGenerator:: +GenerateFieldBuilderInitializationCode(io::Printer* printer) const { + // noop for primitives +} + +void RepeatedPrimitiveFieldGenerator:: GenerateInitializationCode(io::Printer* printer) const { - // Initialized inline. + printer->Print(variables_, "$name$_ = $empty_list$;\n"); +} + +void RepeatedPrimitiveFieldGenerator:: +GenerateBuilderClearCode(io::Printer* printer) const { + printer->Print(variables_, + "$name$_ = $empty_list$;\n" + "$clear_mutable_bit_builder$;\n"); } void RepeatedPrimitiveFieldGenerator:: GenerateMergingCode(io::Printer* printer) const { + // The code below does two optimizations: + // 1. If the other list is empty, there's nothing to do. This ensures we + // don't allocate a new array if we already have an immutable one. + // 2. If the other list is non-empty and our current list is empty, we can + // reuse the other list which is guaranteed to be immutable. printer->Print(variables_, "if (!other.$name$_.isEmpty()) {\n" - " if (result.$name$_.isEmpty()) {\n" - " result.$name$_ = new java.util.ArrayList<$boxed_type$>();\n" + " if ($name$_.isEmpty()) {\n" + " $name$_ = other.$name$_;\n" + " $clear_mutable_bit_builder$;\n" + " } else {\n" + " ensure$capitalized_name$IsMutable();\n" + " $name$_.addAll(other.$name$_);\n" " }\n" - " result.$name$_.addAll(other.$name$_);\n" + " $on_changed$\n" "}\n"); } void RepeatedPrimitiveFieldGenerator:: GenerateBuildingCode(io::Printer* printer) const { + // The code below ensures that the result has an immutable list. If our + // list is immutable, we can just reuse it. If not, we make it immutable. printer->Print(variables_, - "if (result.$name$_ != java.util.Collections.EMPTY_LIST) {\n" - " result.$name$_ =\n" - " java.util.Collections.unmodifiableList(result.$name$_);\n" - "}\n"); + "if ($get_mutable_bit_builder$) {\n" + " $name$_ = java.util.Collections.unmodifiableList($name$_);\n" + " $clear_mutable_bit_builder$;\n" + "}\n" + "result.$name$_ = $name$_;\n"); } void RepeatedPrimitiveFieldGenerator:: GenerateParsingCode(io::Printer* printer) const { printer->Print(variables_, - "add$capitalized_name$(input.read$capitalized_type$());\n"); + "ensure$capitalized_name$IsMutable();\n" + "$name$_.add(input.read$capitalized_type$());\n"); } void RepeatedPrimitiveFieldGenerator:: @@ -401,13 +639,13 @@ GenerateSerializationCode(io::Printer* printer) const { " output.writeRawVarint32($tag$);\n" " output.writeRawVarint32($name$MemoizedSerializedSize);\n" "}\n" - "for ($type$ element : get$capitalized_name$List()) {\n" - " output.write$capitalized_type$NoTag(element);\n" + "for (int i = 0; i < $name$_.size(); i++) {\n" + " output.write$capitalized_type$NoTag($name$_.get(i));\n" "}\n"); } else { printer->Print(variables_, - "for ($type$ element : get$capitalized_name$List()) {\n" - " output.write$capitalized_type$($number$, element);\n" + "for (int i = 0; i < $name$_.size(); i++) {\n" + " output.write$capitalized_type$($number$, $name$_.get(i));\n" "}\n"); } } @@ -421,9 +659,9 @@ GenerateSerializedSizeCode(io::Printer* printer) const { if (FixedSize(GetType(descriptor_)) == -1) { printer->Print(variables_, - "for ($type$ element : get$capitalized_name$List()) {\n" + "for (int i = 0; i < $name$_.size(); i++) {\n" " dataSize += com.google.protobuf.CodedOutputStream\n" - " .compute$capitalized_type$SizeNoTag(element);\n" + " .compute$capitalized_type$SizeNoTag($name$_.get(i));\n" "}\n"); } else { printer->Print(variables_, @@ -455,6 +693,22 @@ GenerateSerializedSizeCode(io::Printer* printer) const { printer->Print("}\n"); } +void RepeatedPrimitiveFieldGenerator:: +GenerateEqualsCode(io::Printer* printer) const { + printer->Print(variables_, + "result = result && get$capitalized_name$List()\n" + " .equals(other.get$capitalized_name$List());\n"); +} + +void RepeatedPrimitiveFieldGenerator:: +GenerateHashCode(io::Printer* printer) const { + printer->Print(variables_, + "if (get$capitalized_name$Count() > 0) {\n" + " hash = (37 * hash) + $constant_name$;\n" + " hash = (53 * hash) + get$capitalized_name$List().hashCode();\n" + "}\n"); +} + string RepeatedPrimitiveFieldGenerator::GetBoxedType() const { return BoxedPrimitiveTypeName(GetJavaType(descriptor_)); } diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_primitive_field.h b/third_party/protobuf/src/google/protobuf/compiler/java/java_primitive_field.h index 4e482a0..7900fac 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_primitive_field.h +++ b/third_party/protobuf/src/google/protobuf/compiler/java/java_primitive_field.h @@ -46,49 +46,69 @@ namespace java { class PrimitiveFieldGenerator : public FieldGenerator { public: - explicit PrimitiveFieldGenerator(const FieldDescriptor* descriptor); + explicit PrimitiveFieldGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, int builderBitIndex); ~PrimitiveFieldGenerator(); // implements FieldGenerator --------------------------------------- + int GetNumBitsForMessage() const; + int GetNumBitsForBuilder() const; + void GenerateInterfaceMembers(io::Printer* printer) const; void GenerateMembers(io::Printer* printer) const; void GenerateBuilderMembers(io::Printer* printer) const; void GenerateInitializationCode(io::Printer* printer) const; + void GenerateBuilderClearCode(io::Printer* printer) const; void GenerateMergingCode(io::Printer* printer) const; void GenerateBuildingCode(io::Printer* printer) const; void GenerateParsingCode(io::Printer* printer) const; void GenerateSerializationCode(io::Printer* printer) const; void GenerateSerializedSizeCode(io::Printer* printer) const; + void GenerateFieldBuilderInitializationCode(io::Printer* printer) const; + void GenerateEqualsCode(io::Printer* printer) const; + void GenerateHashCode(io::Printer* printer) const; string GetBoxedType() const; private: const FieldDescriptor* descriptor_; map<string, string> variables_; + const int messageBitIndex_; + const int builderBitIndex_; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(PrimitiveFieldGenerator); }; class RepeatedPrimitiveFieldGenerator : public FieldGenerator { public: - explicit RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor); + explicit RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, int builderBitIndex); ~RepeatedPrimitiveFieldGenerator(); // implements FieldGenerator --------------------------------------- + int GetNumBitsForMessage() const; + int GetNumBitsForBuilder() const; + void GenerateInterfaceMembers(io::Printer* printer) const; void GenerateMembers(io::Printer* printer) const; void GenerateBuilderMembers(io::Printer* printer) const; void GenerateInitializationCode(io::Printer* printer) const; + void GenerateBuilderClearCode(io::Printer* printer) const; void GenerateMergingCode(io::Printer* printer) const; void GenerateBuildingCode(io::Printer* printer) const; void GenerateParsingCode(io::Printer* printer) const; void GenerateParsingCodeFromPacked(io::Printer* printer) const; void GenerateSerializationCode(io::Printer* printer) const; void GenerateSerializedSizeCode(io::Printer* printer) const; + void GenerateFieldBuilderInitializationCode(io::Printer* printer) const; + void GenerateEqualsCode(io::Printer* printer) const; + void GenerateHashCode(io::Printer* printer) const; string GetBoxedType() const; private: const FieldDescriptor* descriptor_; map<string, string> variables_; + const int messageBitIndex_; + const int builderBitIndex_; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPrimitiveFieldGenerator); }; diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_service.cc b/third_party/protobuf/src/google/protobuf/compiler/java/java_service.cc index 5545bf7..1ae4f46 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/java/java_service.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/java/java_service.cc @@ -118,7 +118,7 @@ void ServiceGenerator::GenerateNewReflectiveServiceMethod( for (int i = 0; i < descriptor_->method_count(); i++) { const MethodDescriptor* method = descriptor_->method(i); - printer->Print("@Override\n"); + printer->Print("@java.lang.Override\n"); GenerateMethodSignature(printer, method, IS_CONCRETE); printer->Print( " {\n" diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_string_field.cc b/third_party/protobuf/src/google/protobuf/compiler/java/java_string_field.cc new file mode 100644 index 0000000..a93ff43 --- /dev/null +++ b/third_party/protobuf/src/google/protobuf/compiler/java/java_string_field.cc @@ -0,0 +1,605 @@ +// 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) +// Author: jonp@google.com (Jon Perlow) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include <map> +#include <string> + +#include <google/protobuf/compiler/java/java_string_field.h> +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/compiler/java/java_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 java { + +using internal::WireFormat; +using internal::WireFormatLite; + +namespace { + +void SetPrimitiveVariables(const FieldDescriptor* descriptor, + int messageBitIndex, + int builderBitIndex, + map<string, string>* variables) { + (*variables)["name"] = + UnderscoresToCamelCase(descriptor); + (*variables)["capitalized_name"] = + UnderscoresToCapitalizedCamelCase(descriptor); + (*variables)["constant_name"] = FieldConstantName(descriptor); + (*variables)["number"] = SimpleItoa(descriptor->number()); + (*variables)["empty_list"] = "com.google.protobuf.LazyStringArrayList.EMPTY"; + + (*variables)["default"] = DefaultValue(descriptor); + (*variables)["default_init"] = ("= " + DefaultValue(descriptor)); + (*variables)["capitalized_type"] = "String"; + (*variables)["tag"] = SimpleItoa(WireFormat::MakeTag(descriptor)); + (*variables)["tag_size"] = SimpleItoa( + WireFormat::TagSize(descriptor->number(), GetType(descriptor))); + (*variables)["null_check"] = + " if (value == null) {\n" + " throw new NullPointerException();\n" + " }\n"; + + // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported + // by the proto compiler + (*variables)["deprecation"] = descriptor->options().deprecated() + ? "@java.lang.Deprecated " : ""; + (*variables)["on_changed"] = + HasDescriptorMethods(descriptor->containing_type()) ? "onChanged();" : ""; + + // For singular messages and builders, one bit is used for the hasField bit. + (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex); + + (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex); + (*variables)["set_has_field_bit_builder"] = GenerateSetBit(builderBitIndex); + (*variables)["clear_has_field_bit_builder"] = + GenerateClearBit(builderBitIndex); + + // For repated builders, one bit is used for whether the array is immutable. + (*variables)["get_mutable_bit_builder"] = GenerateGetBit(builderBitIndex); + (*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex); + (*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex); + + (*variables)["get_has_field_bit_from_local"] = + GenerateGetBitFromLocal(builderBitIndex); + (*variables)["set_has_field_bit_to_local"] = + GenerateSetBitToLocal(messageBitIndex); +} + +} // namespace + +// =================================================================== + +StringFieldGenerator:: +StringFieldGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, + int builderBitIndex) + : descriptor_(descriptor), messageBitIndex_(messageBitIndex), + builderBitIndex_(builderBitIndex) { + SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex, + &variables_); +} + +StringFieldGenerator::~StringFieldGenerator() {} + +int StringFieldGenerator::GetNumBitsForMessage() const { + return 1; +} + +int StringFieldGenerator::GetNumBitsForBuilder() const { + return 1; +} + +// A note about how strings are handled. This code used to just store a String +// in the Message. This had two issues: +// +// 1. It wouldn't roundtrip byte arrays that were not vaid UTF-8 encoded +// strings, but rather fields that were raw bytes incorrectly marked +// as strings in the proto file. This is common because in the proto1 +// syntax, string was the way to indicate bytes and C++ engineers can +// easily make this mistake without affecting the C++ API. By converting to +// strings immediately, some java code might corrupt these byte arrays as +// it passes through a java server even if the field was never accessed by +// application code. +// +// 2. There's a performance hit to converting between bytes and strings and +// it many cases, the field is never even read by the application code. This +// avoids unnecessary conversions in the common use cases. +// +// So now, the field for String is maintained as an Object reference which can +// either store a String or a ByteString. The code uses an instanceof check +// to see which one it has and converts to the other one if needed. It remembers +// the last value requested (in a thread safe manner) as this is most likely +// the one needed next. The thread safety is such that if two threads both +// convert the field because the changes made by each thread were not visible to +// the other, they may cause a conversion to happen more times than would +// otherwise be necessary. This was deemed better than adding synchronization +// overhead. It will not cause any corruption issues or affect the behavior of +// the API. The instanceof check is also highly optimized in the JVM and we +// decided it was better to reduce the memory overhead by not having two +// separate fields but rather use dynamic type checking. +// +// For single fields, the logic for this is done inside the generated code. For +// repeated fields, the logic is done in LazyStringArrayList and +// UnmodifiableLazyStringList. +void StringFieldGenerator:: +GenerateInterfaceMembers(io::Printer* printer) const { + printer->Print(variables_, + "$deprecation$boolean has$capitalized_name$();\n" + "$deprecation$String get$capitalized_name$();\n"); +} + +void StringFieldGenerator:: +GenerateMembers(io::Printer* printer) const { + printer->Print(variables_, + "private Object $name$_;\n" + "$deprecation$public boolean has$capitalized_name$() {\n" + " return $get_has_field_bit_message$;\n" + "}\n"); + + printer->Print(variables_, + "$deprecation$public String get$capitalized_name$() {\n" + " Object ref = $name$_;\n" + " if (ref instanceof String) {\n" + " return (String) ref;\n" + " } else {\n" + " com.google.protobuf.ByteString bs = \n" + " (com.google.protobuf.ByteString) ref;\n" + " String s = bs.toStringUtf8();\n" + " if (com.google.protobuf.Internal.isValidUtf8(bs)) {\n" + " $name$_ = s;\n" + " }\n" + " return s;\n" + " }\n" + "}\n" + "private com.google.protobuf.ByteString get$capitalized_name$Bytes() {\n" + " Object ref = $name$_;\n" + " if (ref instanceof String) {\n" + " com.google.protobuf.ByteString b = \n" + " com.google.protobuf.ByteString.copyFromUtf8((String) ref);\n" + " $name$_ = b;\n" + " return b;\n" + " } else {\n" + " return (com.google.protobuf.ByteString) ref;\n" + " }\n" + "}\n"); +} + +void StringFieldGenerator:: +GenerateBuilderMembers(io::Printer* printer) const { + printer->Print(variables_, + "private Object $name$_ $default_init$;\n" + "$deprecation$public boolean has$capitalized_name$() {\n" + " return $get_has_field_bit_builder$;\n" + "}\n"); + + printer->Print(variables_, + "$deprecation$public String get$capitalized_name$() {\n" + " Object ref = $name$_;\n" + " if (!(ref instanceof String)) {\n" + " String s = ((com.google.protobuf.ByteString) ref).toStringUtf8();\n" + " $name$_ = s;\n" + " return s;\n" + " } else {\n" + " return (String) ref;\n" + " }\n" + "}\n"); + + printer->Print(variables_, + "$deprecation$public Builder set$capitalized_name$(String value) {\n" + "$null_check$" + " $set_has_field_bit_builder$;\n" + " $name$_ = value;\n" + " $on_changed$\n" + " return this;\n" + "}\n" + "$deprecation$public Builder clear$capitalized_name$() {\n" + " $clear_has_field_bit_builder$;\n"); + // The default value is not a simple literal so we want to avoid executing + // it multiple times. Instead, get the default out of the default instance. + printer->Print(variables_, + " $name$_ = getDefaultInstance().get$capitalized_name$();\n"); + printer->Print(variables_, + " $on_changed$\n" + " return this;\n" + "}\n"); + + printer->Print(variables_, + "void set$capitalized_name$(com.google.protobuf.ByteString value) {\n" + " $set_has_field_bit_builder$;\n" + " $name$_ = value;\n" + " $on_changed$\n" + "}\n"); +} + +void StringFieldGenerator:: +GenerateFieldBuilderInitializationCode(io::Printer* printer) const { + // noop for primitives +} + +void StringFieldGenerator:: +GenerateInitializationCode(io::Printer* printer) const { + printer->Print(variables_, "$name$_ = $default$;\n"); +} + +void StringFieldGenerator:: +GenerateBuilderClearCode(io::Printer* printer) const { + printer->Print(variables_, + "$name$_ = $default$;\n" + "$clear_has_field_bit_builder$;\n"); +} + +void StringFieldGenerator:: +GenerateMergingCode(io::Printer* printer) const { + printer->Print(variables_, + "if (other.has$capitalized_name$()) {\n" + " set$capitalized_name$(other.get$capitalized_name$());\n" + "}\n"); +} + +void StringFieldGenerator:: +GenerateBuildingCode(io::Printer* printer) const { + printer->Print(variables_, + "if ($get_has_field_bit_from_local$) {\n" + " $set_has_field_bit_to_local$;\n" + "}\n" + "result.$name$_ = $name$_;\n"); +} + +void StringFieldGenerator:: +GenerateParsingCode(io::Printer* printer) const { + printer->Print(variables_, + "$set_has_field_bit_builder$;\n" + "$name$_ = input.readBytes();\n"); +} + +void StringFieldGenerator:: +GenerateSerializationCode(io::Printer* printer) const { + printer->Print(variables_, + "if ($get_has_field_bit_message$) {\n" + " output.writeBytes($number$, get$capitalized_name$Bytes());\n" + "}\n"); +} + +void StringFieldGenerator:: +GenerateSerializedSizeCode(io::Printer* printer) const { + printer->Print(variables_, + "if ($get_has_field_bit_message$) {\n" + " size += com.google.protobuf.CodedOutputStream\n" + " .computeBytesSize($number$, get$capitalized_name$Bytes());\n" + "}\n"); +} + +void StringFieldGenerator:: +GenerateEqualsCode(io::Printer* printer) const { + printer->Print(variables_, + "result = result && get$capitalized_name$()\n" + " .equals(other.get$capitalized_name$());\n"); +} + +void StringFieldGenerator:: +GenerateHashCode(io::Printer* printer) const { + printer->Print(variables_, + "hash = (37 * hash) + $constant_name$;\n"); + printer->Print(variables_, + "hash = (53 * hash) + get$capitalized_name$().hashCode();\n"); +} + +string StringFieldGenerator::GetBoxedType() const { + return "String"; +} + + +// =================================================================== + +RepeatedStringFieldGenerator:: +RepeatedStringFieldGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, + int builderBitIndex) + : descriptor_(descriptor), messageBitIndex_(messageBitIndex), + builderBitIndex_(builderBitIndex) { + SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex, + &variables_); +} + +RepeatedStringFieldGenerator::~RepeatedStringFieldGenerator() {} + +int RepeatedStringFieldGenerator::GetNumBitsForMessage() const { + return 0; +} + +int RepeatedStringFieldGenerator::GetNumBitsForBuilder() const { + return 1; +} + +void RepeatedStringFieldGenerator:: +GenerateInterfaceMembers(io::Printer* printer) const { + printer->Print(variables_, + "$deprecation$java.util.List<String> get$capitalized_name$List();\n" + "$deprecation$int get$capitalized_name$Count();\n" + "$deprecation$String get$capitalized_name$(int index);\n"); +} + + +void RepeatedStringFieldGenerator:: +GenerateMembers(io::Printer* printer) const { + printer->Print(variables_, + "private com.google.protobuf.LazyStringList $name$_;\n" + "$deprecation$public java.util.List<String>\n" + " get$capitalized_name$List() {\n" + " return $name$_;\n" // note: unmodifiable list + "}\n" + "$deprecation$public int get$capitalized_name$Count() {\n" + " return $name$_.size();\n" + "}\n" + "$deprecation$public String get$capitalized_name$(int index) {\n" + " return $name$_.get(index);\n" + "}\n"); + + if (descriptor_->options().packed() && + HasGeneratedMethods(descriptor_->containing_type())) { + printer->Print(variables_, + "private int $name$MemoizedSerializedSize = -1;\n"); + } +} + +void RepeatedStringFieldGenerator:: +GenerateBuilderMembers(io::Printer* printer) const { + // One field is the list and the bit field keeps track of whether the + // list is immutable. If it's immutable, the invariant is that it must + // either an instance of Collections.emptyList() or it's an ArrayList + // wrapped in a Collections.unmodifiableList() wrapper and nobody else has + // a refererence to the underlying ArrayList. This invariant allows us to + // share instances of lists between protocol buffers avoiding expensive + // memory allocations. Note, immutable is a strong guarantee here -- not + // just that the list cannot be modified via the reference but that the + // list can never be modified. + printer->Print(variables_, + "private com.google.protobuf.LazyStringList $name$_ = $empty_list$;\n"); + + printer->Print(variables_, + "private void ensure$capitalized_name$IsMutable() {\n" + " if (!$get_mutable_bit_builder$) {\n" + " $name$_ = new com.google.protobuf.LazyStringArrayList($name$_);\n" + " $set_mutable_bit_builder$;\n" + " }\n" + "}\n"); + + // Note: We return an unmodifiable list because otherwise the caller + // could hold on to the returned list and modify it after the message + // has been built, thus mutating the message which is supposed to be + // immutable. + printer->Print(variables_, + "$deprecation$public java.util.List<String>\n" + " get$capitalized_name$List() {\n" + " return java.util.Collections.unmodifiableList($name$_);\n" + "}\n" + "$deprecation$public int get$capitalized_name$Count() {\n" + " return $name$_.size();\n" + "}\n" + "$deprecation$public String get$capitalized_name$(int index) {\n" + " return $name$_.get(index);\n" + "}\n" + "$deprecation$public Builder set$capitalized_name$(\n" + " int index, String value) {\n" + "$null_check$" + " ensure$capitalized_name$IsMutable();\n" + " $name$_.set(index, value);\n" + " $on_changed$\n" + " return this;\n" + "}\n" + "$deprecation$public Builder add$capitalized_name$(String value) {\n" + "$null_check$" + " ensure$capitalized_name$IsMutable();\n" + " $name$_.add(value);\n" + " $on_changed$\n" + " return this;\n" + "}\n" + "$deprecation$public Builder addAll$capitalized_name$(\n" + " java.lang.Iterable<String> values) {\n" + " ensure$capitalized_name$IsMutable();\n" + " super.addAll(values, $name$_);\n" + " $on_changed$\n" + " return this;\n" + "}\n" + "$deprecation$public Builder clear$capitalized_name$() {\n" + " $name$_ = $empty_list$;\n" + " $clear_mutable_bit_builder$;\n" + " $on_changed$\n" + " return this;\n" + "}\n"); + + printer->Print(variables_, + "void add$capitalized_name$(com.google.protobuf.ByteString value) {\n" + " ensure$capitalized_name$IsMutable();\n" + " $name$_.add(value);\n" + " $on_changed$\n" + "}\n"); +} + +void RepeatedStringFieldGenerator:: +GenerateFieldBuilderInitializationCode(io::Printer* printer) const { + // noop for primitives +} + +void RepeatedStringFieldGenerator:: +GenerateInitializationCode(io::Printer* printer) const { + printer->Print(variables_, "$name$_ = $empty_list$;\n"); +} + +void RepeatedStringFieldGenerator:: +GenerateBuilderClearCode(io::Printer* printer) const { + printer->Print(variables_, + "$name$_ = $empty_list$;\n" + "$clear_mutable_bit_builder$;\n"); +} + +void RepeatedStringFieldGenerator:: +GenerateMergingCode(io::Printer* printer) const { + // The code below does two optimizations: + // 1. If the other list is empty, there's nothing to do. This ensures we + // don't allocate a new array if we already have an immutable one. + // 2. If the other list is non-empty and our current list is empty, we can + // reuse the other list which is guaranteed to be immutable. + printer->Print(variables_, + "if (!other.$name$_.isEmpty()) {\n" + " if ($name$_.isEmpty()) {\n" + " $name$_ = other.$name$_;\n" + " $clear_mutable_bit_builder$;\n" + " } else {\n" + " ensure$capitalized_name$IsMutable();\n" + " $name$_.addAll(other.$name$_);\n" + " }\n" + " $on_changed$\n" + "}\n"); +} + +void RepeatedStringFieldGenerator:: +GenerateBuildingCode(io::Printer* printer) const { + // The code below ensures that the result has an immutable list. If our + // list is immutable, we can just reuse it. If not, we make it immutable. + + printer->Print(variables_, + "if ($get_mutable_bit_builder$) {\n" + " $name$_ = new com.google.protobuf.UnmodifiableLazyStringList(\n" + " $name$_);\n" + " $clear_mutable_bit_builder$;\n" + "}\n" + "result.$name$_ = $name$_;\n"); +} + +void RepeatedStringFieldGenerator:: +GenerateParsingCode(io::Printer* printer) const { + printer->Print(variables_, + "ensure$capitalized_name$IsMutable();\n" + "$name$_.add(input.readBytes());\n"); +} + +void RepeatedStringFieldGenerator:: +GenerateParsingCodeFromPacked(io::Printer* printer) const { + printer->Print(variables_, + "int length = input.readRawVarint32();\n" + "int limit = input.pushLimit(length);\n" + "while (input.getBytesUntilLimit() > 0) {\n" + " add$capitalized_name$(input.read$capitalized_type$());\n" + "}\n" + "input.popLimit(limit);\n"); +} + +void RepeatedStringFieldGenerator:: +GenerateSerializationCode(io::Printer* printer) const { + if (descriptor_->options().packed()) { + printer->Print(variables_, + "if (get$capitalized_name$List().size() > 0) {\n" + " output.writeRawVarint32($tag$);\n" + " output.writeRawVarint32($name$MemoizedSerializedSize);\n" + "}\n" + "for (int i = 0; i < $name$_.size(); i++) {\n" + " output.write$capitalized_type$NoTag($name$_.get(i));\n" + "}\n"); + } else { + printer->Print(variables_, + "for (int i = 0; i < $name$_.size(); i++) {\n" + " output.writeBytes($number$, $name$_.getByteString(i));\n" + "}\n"); + } +} + +void RepeatedStringFieldGenerator:: +GenerateSerializedSizeCode(io::Printer* printer) const { + printer->Print(variables_, + "{\n" + " int dataSize = 0;\n"); + printer->Indent(); + + printer->Print(variables_, + "for (int i = 0; i < $name$_.size(); i++) {\n" + " dataSize += com.google.protobuf.CodedOutputStream\n" + " .computeBytesSizeNoTag($name$_.getByteString(i));\n" + "}\n"); + + printer->Print( + "size += dataSize;\n"); + + if (descriptor_->options().packed()) { + printer->Print(variables_, + "if (!get$capitalized_name$List().isEmpty()) {\n" + " size += $tag_size$;\n" + " size += com.google.protobuf.CodedOutputStream\n" + " .computeInt32SizeNoTag(dataSize);\n" + "}\n"); + } else { + printer->Print(variables_, + "size += $tag_size$ * get$capitalized_name$List().size();\n"); + } + + // cache the data size for packed fields. + if (descriptor_->options().packed()) { + printer->Print(variables_, + "$name$MemoizedSerializedSize = dataSize;\n"); + } + + printer->Outdent(); + printer->Print("}\n"); +} + +void RepeatedStringFieldGenerator:: +GenerateEqualsCode(io::Printer* printer) const { + printer->Print(variables_, + "result = result && get$capitalized_name$List()\n" + " .equals(other.get$capitalized_name$List());\n"); +} + +void RepeatedStringFieldGenerator:: +GenerateHashCode(io::Printer* printer) const { + printer->Print(variables_, + "if (get$capitalized_name$Count() > 0) {\n" + " hash = (37 * hash) + $constant_name$;\n" + " hash = (53 * hash) + get$capitalized_name$List().hashCode();\n" + "}\n"); +} + +string RepeatedStringFieldGenerator::GetBoxedType() const { + return "String"; +} + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/third_party/protobuf/src/google/protobuf/compiler/java/java_string_field.h b/third_party/protobuf/src/google/protobuf/compiler/java/java_string_field.h new file mode 100644 index 0000000..8cb4146 --- /dev/null +++ b/third_party/protobuf/src/google/protobuf/compiler/java/java_string_field.h @@ -0,0 +1,120 @@ +// 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) +// Author: jonp@google.com (Jon Perlow) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_STRING_FIELD_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_STRING_FIELD_H__ + +#include <map> +#include <string> +#include <google/protobuf/compiler/java/java_field.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +class StringFieldGenerator : public FieldGenerator { + public: + explicit StringFieldGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, int builderBitIndex); + ~StringFieldGenerator(); + + // implements FieldGenerator --------------------------------------- + int GetNumBitsForMessage() const; + int GetNumBitsForBuilder() const; + void GenerateInterfaceMembers(io::Printer* printer) const; + void GenerateMembers(io::Printer* printer) const; + void GenerateBuilderMembers(io::Printer* printer) const; + void GenerateInitializationCode(io::Printer* printer) const; + void GenerateBuilderClearCode(io::Printer* printer) const; + void GenerateMergingCode(io::Printer* printer) const; + void GenerateBuildingCode(io::Printer* printer) const; + void GenerateParsingCode(io::Printer* printer) const; + void GenerateSerializationCode(io::Printer* printer) const; + void GenerateSerializedSizeCode(io::Printer* printer) const; + void GenerateFieldBuilderInitializationCode(io::Printer* printer) const; + void GenerateEqualsCode(io::Printer* printer) const; + void GenerateHashCode(io::Printer* printer) const; + string GetBoxedType() const; + + private: + const FieldDescriptor* descriptor_; + map<string, string> variables_; + const int messageBitIndex_; + const int builderBitIndex_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StringFieldGenerator); +}; + +class RepeatedStringFieldGenerator : public FieldGenerator { + public: + explicit RepeatedStringFieldGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, int builderBitIndex); + ~RepeatedStringFieldGenerator(); + + // implements FieldGenerator --------------------------------------- + int GetNumBitsForMessage() const; + int GetNumBitsForBuilder() const; + void GenerateInterfaceMembers(io::Printer* printer) const; + void GenerateMembers(io::Printer* printer) const; + void GenerateBuilderMembers(io::Printer* printer) const; + void GenerateInitializationCode(io::Printer* printer) const; + void GenerateBuilderClearCode(io::Printer* printer) const; + void GenerateMergingCode(io::Printer* printer) const; + void GenerateBuildingCode(io::Printer* printer) const; + void GenerateParsingCode(io::Printer* printer) const; + void GenerateParsingCodeFromPacked(io::Printer* printer) const; + void GenerateSerializationCode(io::Printer* printer) const; + void GenerateSerializedSizeCode(io::Printer* printer) const; + void GenerateFieldBuilderInitializationCode(io::Printer* printer) const; + void GenerateEqualsCode(io::Printer* printer) const; + void GenerateHashCode(io::Printer* printer) const; + string GetBoxedType() const; + + private: + const FieldDescriptor* descriptor_; + map<string, string> variables_; + const int messageBitIndex_; + const int builderBitIndex_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedStringFieldGenerator); +}; + +} // namespace java +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_STRING_FIELD_H__ diff --git a/third_party/protobuf/src/google/protobuf/compiler/mock_code_generator.cc b/third_party/protobuf/src/google/protobuf/compiler/mock_code_generator.cc index 83d5a4e..5b76af2 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/mock_code_generator.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/mock_code_generator.cc @@ -45,6 +45,16 @@ namespace google { namespace protobuf { namespace compiler { +// Returns the list of the names of files in all_files in the form of a +// comma-separated string. +string CommaSeparatedList(const vector<const FileDescriptor*> all_files) { + vector<string> names; + for (int i = 0; i < all_files.size(); i++) { + names.push_back(all_files[i]->name()); + } + return JoinStrings(names, ","); +} + static const char* kFirstInsertionPointName = "first_mock_insertion_point"; static const char* kSecondInsertionPointName = "second_mock_insertion_point"; static const char* kFirstInsertionPoint = @@ -63,6 +73,7 @@ void MockCodeGenerator::ExpectGenerated( const string& insertions, const string& file, const string& first_message_name, + const string& first_parsed_file_name, const string& output_directory) { string content; ASSERT_TRUE(File::ReadFileToString( @@ -84,7 +95,8 @@ void MockCodeGenerator::ExpectGenerated( } ASSERT_EQ(lines.size(), 3 + insertion_list.size() * 2); - EXPECT_EQ(GetOutputFileContent(name, parameter, file, first_message_name), + EXPECT_EQ(GetOutputFileContent(name, parameter, file, + first_parsed_file_name, first_message_name), lines[0]); EXPECT_EQ(kFirstInsertionPoint, lines[1 + insertion_list.size()]); @@ -92,12 +104,12 @@ void MockCodeGenerator::ExpectGenerated( for (int i = 0; i < insertion_list.size(); i++) { EXPECT_EQ(GetOutputFileContent(insertion_list[i], "first_insert", - file, first_message_name), + file, file, first_message_name), lines[1 + i]); // Second insertion point is indented, so the inserted text should // automatically be indented too. EXPECT_EQ(" " + GetOutputFileContent(insertion_list[i], "second_insert", - file, first_message_name), + file, file, first_message_name), lines[2 + insertion_list.size() + i]); } } @@ -105,7 +117,7 @@ void MockCodeGenerator::ExpectGenerated( bool MockCodeGenerator::Generate( const FileDescriptor* file, const string& parameter, - OutputDirectory* output_directory, + GeneratorContext* context, string* error) const { for (int i = 0; i < file->message_type_count(); i++) { if (HasPrefixString(file->message_type(i)->name(), "MockCodeGenerator_")) { @@ -134,11 +146,12 @@ bool MockCodeGenerator::Generate( for (int i = 0; i < insert_into.size(); i++) { { scoped_ptr<io::ZeroCopyOutputStream> output( - output_directory->OpenForInsert( + context->OpenForInsert( GetOutputFileName(insert_into[i], file), kFirstInsertionPointName)); io::Printer printer(output.get(), '$'); - printer.PrintRaw(GetOutputFileContent(name_, "first_insert", file)); + printer.PrintRaw(GetOutputFileContent(name_, "first_insert", + file, context)); if (printer.failed()) { *error = "MockCodeGenerator detected write error."; return false; @@ -147,11 +160,12 @@ bool MockCodeGenerator::Generate( { scoped_ptr<io::ZeroCopyOutputStream> output( - output_directory->OpenForInsert( + context->OpenForInsert( GetOutputFileName(insert_into[i], file), kSecondInsertionPointName)); io::Printer printer(output.get(), '$'); - printer.PrintRaw(GetOutputFileContent(name_, "second_insert", file)); + printer.PrintRaw(GetOutputFileContent(name_, "second_insert", + file, context)); if (printer.failed()) { *error = "MockCodeGenerator detected write error."; return false; @@ -160,10 +174,11 @@ bool MockCodeGenerator::Generate( } } else { scoped_ptr<io::ZeroCopyOutputStream> output( - output_directory->Open(GetOutputFileName(name_, file))); + context->Open(GetOutputFileName(name_, file))); io::Printer printer(output.get(), '$'); - printer.PrintRaw(GetOutputFileContent(name_, parameter, file)); + printer.PrintRaw(GetOutputFileContent(name_, parameter, + file, context)); printer.PrintRaw(kFirstInsertionPoint); printer.PrintRaw(kSecondInsertionPoint); @@ -186,11 +201,16 @@ string MockCodeGenerator::GetOutputFileName(const string& generator_name, return file + ".MockCodeGenerator." + generator_name; } -string MockCodeGenerator::GetOutputFileContent(const string& generator_name, - const string& parameter, - const FileDescriptor* file) { +string MockCodeGenerator::GetOutputFileContent( + const string& generator_name, + const string& parameter, + const FileDescriptor* file, + GeneratorContext *context) { + vector<const FileDescriptor*> all_files; + context->ListParsedFiles(&all_files); return GetOutputFileContent( generator_name, parameter, file->name(), + CommaSeparatedList(all_files), file->message_type_count() > 0 ? file->message_type(0)->name() : "(none)"); } @@ -199,9 +219,11 @@ string MockCodeGenerator::GetOutputFileContent( const string& generator_name, const string& parameter, const string& file, + const string& parsed_file_list, const string& first_message_name) { - return strings::Substitute("$0: $1, $2, $3\n", - generator_name, parameter, file, first_message_name); + return strings::Substitute("$0: $1, $2, $3, $4\n", + generator_name, parameter, file, + first_message_name, parsed_file_list); } } // namespace compiler diff --git a/third_party/protobuf/src/google/protobuf/compiler/mock_code_generator.h b/third_party/protobuf/src/google/protobuf/compiler/mock_code_generator.h index 01d69dd..5c7942b 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/mock_code_generator.h +++ b/third_party/protobuf/src/google/protobuf/compiler/mock_code_generator.h @@ -69,11 +69,14 @@ class MockCodeGenerator : public CodeGenerator { // // |insertions| is a comma-separated list of names of MockCodeGenerators which // should have inserted lines into this file. + // |parsed_file_list| is a comma-separated list of names of the files + // that are being compiled together in this run. static void ExpectGenerated(const string& name, const string& parameter, const string& insertions, const string& file, const string& first_message_name, + const string& parsed_file_list, const string& output_directory); // Get the name of the file which would be written by the given generator. @@ -86,7 +89,7 @@ class MockCodeGenerator : public CodeGenerator { virtual bool Generate(const FileDescriptor* file, const string& parameter, - OutputDirectory* output_directory, + GeneratorContext* context, string* error) const; private: @@ -94,10 +97,12 @@ class MockCodeGenerator : public CodeGenerator { static string GetOutputFileContent(const string& generator_name, const string& parameter, - const FileDescriptor* file); + const FileDescriptor* file, + GeneratorContext *context); static string GetOutputFileContent(const string& generator_name, const string& parameter, const string& file, + const string& parsed_file_list, const string& first_message_name); }; diff --git a/third_party/protobuf/src/google/protobuf/compiler/parser.cc b/third_party/protobuf/src/google/protobuf/compiler/parser.cc index 9fcb131..34317b1 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/parser.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/parser.cc @@ -250,20 +250,69 @@ void Parser::AddError(const string& error) { AddError(input_->current().line, input_->current().column, error); } -void Parser::RecordLocation( - const Message* descriptor, - DescriptorPool::ErrorCollector::ErrorLocation location, - int line, int column) { - if (source_location_table_ != NULL) { - source_location_table_->Add(descriptor, location, line, column); +// ------------------------------------------------------------------- + +Parser::LocationRecorder::LocationRecorder(Parser* parser) + : parser_(parser), + location_(parser_->source_code_info_->add_location()) { + location_->add_span(parser_->input_->current().line); + location_->add_span(parser_->input_->current().column); +} + +Parser::LocationRecorder::LocationRecorder(const LocationRecorder& parent) { + Init(parent); +} + +Parser::LocationRecorder::LocationRecorder(const LocationRecorder& parent, + int path1) { + Init(parent); + AddPath(path1); +} + +Parser::LocationRecorder::LocationRecorder(const LocationRecorder& parent, + int path1, int path2) { + Init(parent); + AddPath(path1); + AddPath(path2); +} + +void Parser::LocationRecorder::Init(const LocationRecorder& parent) { + parser_ = parent.parser_; + location_ = parser_->source_code_info_->add_location(); + location_->mutable_path()->CopyFrom(parent.location_->path()); + + location_->add_span(parser_->input_->current().line); + location_->add_span(parser_->input_->current().column); +} + +Parser::LocationRecorder::~LocationRecorder() { + if (location_->span_size() <= 2) { + EndAt(parser_->input_->previous()); } } -void Parser::RecordLocation( - const Message* descriptor, +void Parser::LocationRecorder::AddPath(int path_component) { + location_->add_path(path_component); +} + +void Parser::LocationRecorder::StartAt(const io::Tokenizer::Token& token) { + location_->set_span(0, token.line); + location_->set_span(1, token.column); +} + +void Parser::LocationRecorder::EndAt(const io::Tokenizer::Token& token) { + if (token.line != location_->span(0)) { + location_->add_span(token.line); + } + location_->add_span(token.end_column); +} + +void Parser::LocationRecorder::RecordLegacyLocation(const Message* descriptor, DescriptorPool::ErrorCollector::ErrorLocation location) { - RecordLocation(descriptor, location, - input_->current().line, input_->current().column); + if (parser_->source_location_table_ != NULL) { + parser_->source_location_table_->Add( + descriptor, location, location_->span(0), location_->span(1)); + } } // ------------------------------------------------------------------- @@ -308,38 +357,51 @@ bool Parser::Parse(io::Tokenizer* input, FileDescriptorProto* file) { had_errors_ = false; syntax_identifier_.clear(); + // Note that |file| could be NULL at this point if + // stop_after_syntax_identifier_ is true. So, we conservatively allocate + // SourceCodeInfo on the stack, then swap it into the FileDescriptorProto + // later on. + SourceCodeInfo source_code_info; + source_code_info_ = &source_code_info; + if (LookingAtType(io::Tokenizer::TYPE_START)) { // Advance to first token. input_->Next(); } - if (require_syntax_identifier_ || LookingAt("syntax")) { - if (!ParseSyntaxIdentifier()) { - // Don't attempt to parse the file if we didn't recognize the syntax - // identifier. - return false; + { + LocationRecorder root_location(this); + + if (require_syntax_identifier_ || LookingAt("syntax")) { + if (!ParseSyntaxIdentifier()) { + // Don't attempt to parse the file if we didn't recognize the syntax + // identifier. + return false; + } + } else if (!stop_after_syntax_identifier_) { + syntax_identifier_ = "proto2"; } - } else if (!stop_after_syntax_identifier_) { - syntax_identifier_ = "proto2"; - } - if (stop_after_syntax_identifier_) return !had_errors_; + if (stop_after_syntax_identifier_) return !had_errors_; - // Repeatedly parse statements until we reach the end of the file. - while (!AtEnd()) { - if (!ParseTopLevelStatement(file)) { - // This statement failed to parse. Skip it, but keep looping to parse - // other statements. - SkipStatement(); + // Repeatedly parse statements until we reach the end of the file. + while (!AtEnd()) { + if (!ParseTopLevelStatement(file, root_location)) { + // This statement failed to parse. Skip it, but keep looping to parse + // other statements. + SkipStatement(); - if (LookingAt("}")) { - AddError("Unmatched \"}\"."); - input_->Next(); + if (LookingAt("}")) { + AddError("Unmatched \"}\"."); + input_->Next(); + } } } } input_ = NULL; + source_code_info_ = NULL; + source_code_info.Swap(file->mutable_source_code_info()); return !had_errors_; } @@ -363,25 +425,40 @@ bool Parser::ParseSyntaxIdentifier() { return true; } -bool Parser::ParseTopLevelStatement(FileDescriptorProto* file) { +bool Parser::ParseTopLevelStatement(FileDescriptorProto* file, + const LocationRecorder& root_location) { if (TryConsume(";")) { // empty statement; ignore return true; } else if (LookingAt("message")) { - return ParseMessageDefinition(file->add_message_type()); + LocationRecorder location(root_location, + FileDescriptorProto::kMessageTypeFieldNumber, file->message_type_size()); + return ParseMessageDefinition(file->add_message_type(), location); } else if (LookingAt("enum")) { - return ParseEnumDefinition(file->add_enum_type()); + LocationRecorder location(root_location, + FileDescriptorProto::kEnumTypeFieldNumber, file->enum_type_size()); + return ParseEnumDefinition(file->add_enum_type(), location); } else if (LookingAt("service")) { - return ParseServiceDefinition(file->add_service()); + LocationRecorder location(root_location, + FileDescriptorProto::kServiceFieldNumber, file->service_size()); + return ParseServiceDefinition(file->add_service(), location); } else if (LookingAt("extend")) { + LocationRecorder location(root_location, + FileDescriptorProto::kExtensionFieldNumber); return ParseExtend(file->mutable_extension(), - file->mutable_message_type()); + file->mutable_message_type(), + root_location, + FileDescriptorProto::kMessageTypeFieldNumber, + location); } else if (LookingAt("import")) { - return ParseImport(file->add_dependency()); + int index = file->dependency_size(); + return ParseImport(file->add_dependency(), root_location, index); } else if (LookingAt("package")) { - return ParsePackage(file); + return ParsePackage(file, root_location); } else if (LookingAt("option")) { - return ParseOption(file->mutable_options()); + LocationRecorder location(root_location, + FileDescriptorProto::kOptionsFieldNumber); + return ParseOption(file->mutable_options(), location); } else { AddError("Expected top-level statement (e.g. \"message\")."); return false; @@ -391,15 +468,22 @@ bool Parser::ParseTopLevelStatement(FileDescriptorProto* file) { // ------------------------------------------------------------------- // Messages -bool Parser::ParseMessageDefinition(DescriptorProto* message) { +bool Parser::ParseMessageDefinition(DescriptorProto* message, + const LocationRecorder& message_location) { DO(Consume("message")); - RecordLocation(message, DescriptorPool::ErrorCollector::NAME); - DO(ConsumeIdentifier(message->mutable_name(), "Expected message name.")); - DO(ParseMessageBlock(message)); + { + LocationRecorder location(message_location, + DescriptorProto::kNameFieldNumber); + location.RecordLegacyLocation( + message, DescriptorPool::ErrorCollector::NAME); + DO(ConsumeIdentifier(message->mutable_name(), "Expected message name.")); + } + DO(ParseMessageBlock(message, message_location)); return true; } -bool Parser::ParseMessageBlock(DescriptorProto* message) { +bool Parser::ParseMessageBlock(DescriptorProto* message, + const LocationRecorder& message_location) { DO(Consume("{")); while (!TryConsume("}")) { @@ -408,7 +492,7 @@ bool Parser::ParseMessageBlock(DescriptorProto* message) { return false; } - if (!ParseMessageStatement(message)) { + if (!ParseMessageStatement(message, message_location)) { // This statement failed to parse. Skip it, but keep looping to parse // other statements. SkipStatement(); @@ -418,66 +502,133 @@ bool Parser::ParseMessageBlock(DescriptorProto* message) { return true; } -bool Parser::ParseMessageStatement(DescriptorProto* message) { +bool Parser::ParseMessageStatement(DescriptorProto* message, + const LocationRecorder& message_location) { if (TryConsume(";")) { // empty statement; ignore return true; } else if (LookingAt("message")) { - return ParseMessageDefinition(message->add_nested_type()); + LocationRecorder location(message_location, + DescriptorProto::kNestedTypeFieldNumber, + message->nested_type_size()); + return ParseMessageDefinition(message->add_nested_type(), location); } else if (LookingAt("enum")) { - return ParseEnumDefinition(message->add_enum_type()); + LocationRecorder location(message_location, + DescriptorProto::kEnumTypeFieldNumber, + message->enum_type_size()); + return ParseEnumDefinition(message->add_enum_type(), location); } else if (LookingAt("extensions")) { - return ParseExtensions(message); + LocationRecorder location(message_location, + DescriptorProto::kExtensionRangeFieldNumber); + return ParseExtensions(message, location); } else if (LookingAt("extend")) { + LocationRecorder location(message_location, + DescriptorProto::kExtensionFieldNumber); return ParseExtend(message->mutable_extension(), - message->mutable_nested_type()); + message->mutable_nested_type(), + message_location, + DescriptorProto::kNestedTypeFieldNumber, + location); } else if (LookingAt("option")) { - return ParseOption(message->mutable_options()); + LocationRecorder location(message_location, + DescriptorProto::kOptionsFieldNumber); + return ParseOption(message->mutable_options(), location); } else { + LocationRecorder location(message_location, + DescriptorProto::kFieldFieldNumber, + message->field_size()); return ParseMessageField(message->add_field(), - message->mutable_nested_type()); + message->mutable_nested_type(), + message_location, + DescriptorProto::kNestedTypeFieldNumber, + location); } } bool Parser::ParseMessageField(FieldDescriptorProto* field, - RepeatedPtrField<DescriptorProto>* messages) { + RepeatedPtrField<DescriptorProto>* messages, + const LocationRecorder& parent_location, + int location_field_number_for_nested_type, + const LocationRecorder& field_location) { // Parse label and type. - FieldDescriptorProto::Label label; - DO(ParseLabel(&label)); - field->set_label(label); - - RecordLocation(field, DescriptorPool::ErrorCollector::TYPE); - FieldDescriptorProto::Type type = FieldDescriptorProto::TYPE_INT32; - string type_name; - DO(ParseType(&type, &type_name)); - if (type_name.empty()) { - field->set_type(type); - } else { - field->set_type_name(type_name); + io::Tokenizer::Token label_token = input_->current(); + { + LocationRecorder location(field_location, + FieldDescriptorProto::kLabelFieldNumber); + FieldDescriptorProto::Label label; + DO(ParseLabel(&label)); + field->set_label(label); + } + + { + LocationRecorder location(field_location); // add path later + location.RecordLegacyLocation(field, DescriptorPool::ErrorCollector::TYPE); + + FieldDescriptorProto::Type type = FieldDescriptorProto::TYPE_INT32; + string type_name; + DO(ParseType(&type, &type_name)); + if (type_name.empty()) { + location.AddPath(FieldDescriptorProto::kTypeFieldNumber); + field->set_type(type); + } else { + location.AddPath(FieldDescriptorProto::kTypeNameFieldNumber); + field->set_type_name(type_name); + } } // Parse name and '='. - RecordLocation(field, DescriptorPool::ErrorCollector::NAME); io::Tokenizer::Token name_token = input_->current(); - DO(ConsumeIdentifier(field->mutable_name(), "Expected field name.")); + { + LocationRecorder location(field_location, + FieldDescriptorProto::kNameFieldNumber); + location.RecordLegacyLocation(field, DescriptorPool::ErrorCollector::NAME); + DO(ConsumeIdentifier(field->mutable_name(), "Expected field name.")); + } DO(Consume("=", "Missing field number.")); // Parse field number. - RecordLocation(field, DescriptorPool::ErrorCollector::NUMBER); - int number; - DO(ConsumeInteger(&number, "Expected field number.")); - field->set_number(number); + { + LocationRecorder location(field_location, + FieldDescriptorProto::kNumberFieldNumber); + location.RecordLegacyLocation( + field, DescriptorPool::ErrorCollector::NUMBER); + int number; + DO(ConsumeInteger(&number, "Expected field number.")); + field->set_number(number); + } // Parse options. - DO(ParseFieldOptions(field)); + DO(ParseFieldOptions(field, field_location)); // Deal with groups. - if (type_name.empty() && type == FieldDescriptorProto::TYPE_GROUP) { + if (field->has_type() && field->type() == FieldDescriptorProto::TYPE_GROUP) { + // Awkward: Since a group declares both a message type and a field, we + // have to create overlapping locations. + LocationRecorder group_location(parent_location); + group_location.StartAt(label_token); + group_location.AddPath(location_field_number_for_nested_type); + group_location.AddPath(messages->size()); + DescriptorProto* group = messages->Add(); group->set_name(field->name()); + // Record name location to match the field name's location. - RecordLocation(group, DescriptorPool::ErrorCollector::NAME, - name_token.line, name_token.column); + { + LocationRecorder location(group_location, + DescriptorProto::kNameFieldNumber); + location.StartAt(name_token); + location.EndAt(name_token); + location.RecordLegacyLocation( + group, DescriptorPool::ErrorCollector::NAME); + } + + // The field's type_name also comes from the name. Confusing! + { + LocationRecorder location(field_location, + FieldDescriptorProto::kTypeNameFieldNumber); + location.StartAt(name_token); + location.EndAt(name_token); + } // As a hack for backwards-compatibility, we force the group name to start // with a capital letter and lower-case the field name. New code should @@ -490,7 +641,7 @@ bool Parser::ParseMessageField(FieldDescriptorProto* field, field->set_type_name(group->name()); if (LookingAt("{")) { - DO(ParseMessageBlock(group)); + DO(ParseMessageBlock(group, group_location)); } else { AddError("Missing group body."); return false; @@ -502,15 +653,23 @@ bool Parser::ParseMessageField(FieldDescriptorProto* field, return true; } -bool Parser::ParseFieldOptions(FieldDescriptorProto* field) { - if (!TryConsume("[")) return true; +bool Parser::ParseFieldOptions(FieldDescriptorProto* field, + const LocationRecorder& field_location) { + if (!LookingAt("[")) return true; + + LocationRecorder location(field_location, + FieldDescriptorProto::kOptionsFieldNumber); + + DO(Consume("[")); // Parse field options. do { if (LookingAt("default")) { - DO(ParseDefaultAssignment(field)); + // We intentionally pass field_location rather than location here, since + // the default value is not actually an option. + DO(ParseDefaultAssignment(field, field_location)); } else { - DO(ParseOptionAssignment(field->mutable_options())); + DO(ParseOptionAssignment(field->mutable_options(), location)); } } while (TryConsume(",")); @@ -518,7 +677,8 @@ bool Parser::ParseFieldOptions(FieldDescriptorProto* field) { return true; } -bool Parser::ParseDefaultAssignment(FieldDescriptorProto* field) { +bool Parser::ParseDefaultAssignment(FieldDescriptorProto* field, + const LocationRecorder& field_location) { if (field->has_default_value()) { AddError("Already set option \"default\"."); field->clear_default_value(); @@ -527,7 +687,10 @@ bool Parser::ParseDefaultAssignment(FieldDescriptorProto* field) { DO(Consume("default")); DO(Consume("=")); - RecordLocation(field, DescriptorPool::ErrorCollector::DEFAULT_VALUE); + LocationRecorder location(field_location, + FieldDescriptorProto::kDefaultValueFieldNumber); + location.RecordLegacyLocation( + field, DescriptorPool::ErrorCollector::DEFAULT_VALUE); string* default_value = field->mutable_default_value(); if (!field->has_type()) { @@ -634,26 +797,35 @@ bool Parser::ParseDefaultAssignment(FieldDescriptorProto* field) { return true; } -bool Parser::ParseOptionNamePart(UninterpretedOption* uninterpreted_option) { +bool Parser::ParseOptionNamePart(UninterpretedOption* uninterpreted_option, + const LocationRecorder& part_location) { UninterpretedOption::NamePart* name = uninterpreted_option->add_name(); string identifier; // We parse identifiers into this string. if (LookingAt("(")) { // This is an extension. DO(Consume("(")); - // An extension name consists of dot-separated identifiers, and may begin - // with a dot. - if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) { - DO(ConsumeIdentifier(&identifier, "Expected identifier.")); - name->mutable_name_part()->append(identifier); - } - while (LookingAt(".")) { - DO(Consume(".")); - name->mutable_name_part()->append("."); - DO(ConsumeIdentifier(&identifier, "Expected identifier.")); - name->mutable_name_part()->append(identifier); + + { + LocationRecorder location( + part_location, UninterpretedOption::NamePart::kNamePartFieldNumber); + // An extension name consists of dot-separated identifiers, and may begin + // with a dot. + if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) { + DO(ConsumeIdentifier(&identifier, "Expected identifier.")); + name->mutable_name_part()->append(identifier); + } + while (LookingAt(".")) { + DO(Consume(".")); + name->mutable_name_part()->append("."); + DO(ConsumeIdentifier(&identifier, "Expected identifier.")); + name->mutable_name_part()->append(identifier); + } } + DO(Consume(")")); name->set_is_extension(true); } else { // This is a regular field. + LocationRecorder location( + part_location, UninterpretedOption::NamePart::kNamePartFieldNumber); DO(ConsumeIdentifier(&identifier, "Expected identifier.")); name->mutable_name_part()->append(identifier); name->set_is_extension(false); @@ -661,34 +833,75 @@ bool Parser::ParseOptionNamePart(UninterpretedOption* uninterpreted_option) { return true; } +bool Parser::ParseUninterpretedBlock(string* value) { + // Note that enclosing braces are not added to *value. + DO(Consume("{")); + int brace_depth = 1; + while (!AtEnd()) { + if (LookingAt("{")) { + brace_depth++; + } else if (LookingAt("}")) { + brace_depth--; + if (brace_depth == 0) { + input_->Next(); + return true; + } + } + // TODO(sanjay): Interpret line/column numbers to preserve formatting + if (!value->empty()) value->push_back(' '); + value->append(input_->current().text); + input_->Next(); + } + AddError("Unexpected end of stream while parsing aggregate value."); + return false; +} + // We don't interpret the option here. Instead we store it in an // UninterpretedOption, to be interpreted later. -bool Parser::ParseOptionAssignment(Message* options) { +bool Parser::ParseOptionAssignment(Message* options, + const LocationRecorder& options_location) { // Create an entry in the uninterpreted_option field. const FieldDescriptor* uninterpreted_option_field = options->GetDescriptor()-> FindFieldByName("uninterpreted_option"); GOOGLE_CHECK(uninterpreted_option_field != NULL) << "No field named \"uninterpreted_option\" in the Options proto."; + const Reflection* reflection = options->GetReflection(); + + LocationRecorder location( + options_location, uninterpreted_option_field->number(), + reflection->FieldSize(*options, uninterpreted_option_field)); + UninterpretedOption* uninterpreted_option = down_cast<UninterpretedOption*>( options->GetReflection()->AddMessage(options, uninterpreted_option_field)); // Parse dot-separated name. - RecordLocation(uninterpreted_option, - DescriptorPool::ErrorCollector::OPTION_NAME); - - DO(ParseOptionNamePart(uninterpreted_option)); + { + LocationRecorder name_location(location, + UninterpretedOption::kNameFieldNumber); + name_location.RecordLegacyLocation( + uninterpreted_option, DescriptorPool::ErrorCollector::OPTION_NAME); + + { + LocationRecorder part_location(name_location, + uninterpreted_option->name_size()); + DO(ParseOptionNamePart(uninterpreted_option, part_location)); + } - while (LookingAt(".")) { - DO(Consume(".")); - DO(ParseOptionNamePart(uninterpreted_option)); + while (LookingAt(".")) { + DO(Consume(".")); + LocationRecorder part_location(name_location, + uninterpreted_option->name_size()); + DO(ParseOptionNamePart(uninterpreted_option, part_location)); + } } DO(Consume("=")); - RecordLocation(uninterpreted_option, - DescriptorPool::ErrorCollector::OPTION_VALUE); + LocationRecorder value_location(location); + value_location.RecordLegacyLocation( + uninterpreted_option, DescriptorPool::ErrorCollector::OPTION_VALUE); // All values are a single token, except for negative numbers, which consist // of a single '-' symbol, followed by a positive number. @@ -704,6 +917,7 @@ bool Parser::ParseOptionAssignment(Message* options) { return false; case io::Tokenizer::TYPE_IDENTIFIER: { + value_location.AddPath(UninterpretedOption::kIdentifierValueFieldNumber); if (is_negative) { AddError("Invalid '-' symbol before identifier."); return false; @@ -720,15 +934,19 @@ bool Parser::ParseOptionAssignment(Message* options) { is_negative ? static_cast<uint64>(kint64max) + 1 : kuint64max; DO(ConsumeInteger64(max_value, &value, "Expected integer.")); if (is_negative) { - uninterpreted_option->set_negative_int_value( - -static_cast<int64>(value)); + value_location.AddPath( + UninterpretedOption::kNegativeIntValueFieldNumber); + uninterpreted_option->set_negative_int_value(-static_cast<int64>(value)); } else { + value_location.AddPath( + UninterpretedOption::kPositiveIntValueFieldNumber); uninterpreted_option->set_positive_int_value(value); } break; } case io::Tokenizer::TYPE_FLOAT: { + value_location.AddPath(UninterpretedOption::kDoubleValueFieldNumber); double value; DO(ConsumeNumber(&value, "Expected number.")); uninterpreted_option->set_double_value(is_negative ? -value : value); @@ -736,6 +954,7 @@ bool Parser::ParseOptionAssignment(Message* options) { } case io::Tokenizer::TYPE_STRING: { + value_location.AddPath(UninterpretedOption::kStringValueFieldNumber); if (is_negative) { AddError("Invalid '-' symbol before string."); return false; @@ -747,31 +966,57 @@ bool Parser::ParseOptionAssignment(Message* options) { } case io::Tokenizer::TYPE_SYMBOL: - AddError("Expected option value."); - return false; + if (LookingAt("{")) { + value_location.AddPath(UninterpretedOption::kAggregateValueFieldNumber); + DO(ParseUninterpretedBlock( + uninterpreted_option->mutable_aggregate_value())); + } else { + AddError("Expected option value."); + return false; + } + break; } return true; } -bool Parser::ParseExtensions(DescriptorProto* message) { +bool Parser::ParseExtensions(DescriptorProto* message, + const LocationRecorder& extensions_location) { // Parse the declaration. DO(Consume("extensions")); do { + // Note that kExtensionRangeFieldNumber was already pushed by the parent. + LocationRecorder location(extensions_location, + message->extension_range_size()); + DescriptorProto::ExtensionRange* range = message->add_extension_range(); - RecordLocation(range, DescriptorPool::ErrorCollector::NUMBER); + location.RecordLegacyLocation( + range, DescriptorPool::ErrorCollector::NUMBER); int start, end; - DO(ConsumeInteger(&start, "Expected field number range.")); + io::Tokenizer::Token start_token; + + { + LocationRecorder start_location( + location, DescriptorProto::ExtensionRange::kStartFieldNumber); + start_token = input_->current(); + DO(ConsumeInteger(&start, "Expected field number range.")); + } if (TryConsume("to")) { + LocationRecorder end_location( + location, DescriptorProto::ExtensionRange::kEndFieldNumber); if (TryConsume("max")) { end = FieldDescriptor::kMaxNumber; } else { DO(ConsumeInteger(&end, "Expected integer.")); } } else { + LocationRecorder end_location( + location, DescriptorProto::ExtensionRange::kEndFieldNumber); + end_location.StartAt(start_token); + end_location.EndAt(start_token); end = start; } @@ -788,16 +1033,17 @@ bool Parser::ParseExtensions(DescriptorProto* message) { } bool Parser::ParseExtend(RepeatedPtrField<FieldDescriptorProto>* extensions, - RepeatedPtrField<DescriptorProto>* messages) { + RepeatedPtrField<DescriptorProto>* messages, + const LocationRecorder& parent_location, + int location_field_number_for_nested_type, + const LocationRecorder& extend_location) { DO(Consume("extend")); - // We expect to see at least one extension field defined in the extend block. - // We need to create it now so we can record the extendee's location. - FieldDescriptorProto* first_field = extensions->Add(); - // Parse the extendee type. - RecordLocation(first_field, DescriptorPool::ErrorCollector::EXTENDEE); - DO(ParseUserDefinedType(first_field->mutable_extendee())); + io::Tokenizer::Token extendee_start = input_->current(); + string extendee; + DO(ParseUserDefinedType(&extendee)); + io::Tokenizer::Token extendee_end = input_->previous(); // Parse the block. DO(Consume("{")); @@ -810,16 +1056,29 @@ bool Parser::ParseExtend(RepeatedPtrField<FieldDescriptorProto>* extensions, return false; } - FieldDescriptorProto* field; - if (is_first) { - field = first_field; - is_first = false; - } else { - field = extensions->Add(); - field->set_extendee(first_field->extendee()); + // Note that kExtensionFieldNumber was already pushed by the parent. + LocationRecorder location(extend_location, extensions->size()); + + FieldDescriptorProto* field = extensions->Add(); + + { + LocationRecorder extendee_location( + location, FieldDescriptorProto::kExtendeeFieldNumber); + extendee_location.StartAt(extendee_start); + extendee_location.EndAt(extendee_end); + + if (is_first) { + extendee_location.RecordLegacyLocation( + field, DescriptorPool::ErrorCollector::EXTENDEE); + is_first = false; + } } - if (!ParseMessageField(field, messages)) { + field->set_extendee(extendee); + + if (!ParseMessageField(field, messages, parent_location, + location_field_number_for_nested_type, + location)) { // This statement failed to parse. Skip it, but keep looping to parse // other statements. SkipStatement(); @@ -832,15 +1091,24 @@ bool Parser::ParseExtend(RepeatedPtrField<FieldDescriptorProto>* extensions, // ------------------------------------------------------------------- // Enums -bool Parser::ParseEnumDefinition(EnumDescriptorProto* enum_type) { +bool Parser::ParseEnumDefinition(EnumDescriptorProto* enum_type, + const LocationRecorder& enum_location) { DO(Consume("enum")); - RecordLocation(enum_type, DescriptorPool::ErrorCollector::NAME); - DO(ConsumeIdentifier(enum_type->mutable_name(), "Expected enum name.")); - DO(ParseEnumBlock(enum_type)); + + { + LocationRecorder location(enum_location, + EnumDescriptorProto::kNameFieldNumber); + location.RecordLegacyLocation( + enum_type, DescriptorPool::ErrorCollector::NAME); + DO(ConsumeIdentifier(enum_type->mutable_name(), "Expected enum name.")); + } + + DO(ParseEnumBlock(enum_type, enum_location)); return true; } -bool Parser::ParseEnumBlock(EnumDescriptorProto* enum_type) { +bool Parser::ParseEnumBlock(EnumDescriptorProto* enum_type, + const LocationRecorder& enum_location) { DO(Consume("{")); while (!TryConsume("}")) { @@ -849,7 +1117,7 @@ bool Parser::ParseEnumBlock(EnumDescriptorProto* enum_type) { return false; } - if (!ParseEnumStatement(enum_type)) { + if (!ParseEnumStatement(enum_type, enum_location)) { // This statement failed to parse. Skip it, but keep looping to parse // other statements. SkipStatement(); @@ -859,41 +1127,69 @@ bool Parser::ParseEnumBlock(EnumDescriptorProto* enum_type) { return true; } -bool Parser::ParseEnumStatement(EnumDescriptorProto* enum_type) { +bool Parser::ParseEnumStatement(EnumDescriptorProto* enum_type, + const LocationRecorder& enum_location) { if (TryConsume(";")) { // empty statement; ignore return true; } else if (LookingAt("option")) { - return ParseOption(enum_type->mutable_options()); + LocationRecorder location(enum_location, + EnumDescriptorProto::kOptionsFieldNumber); + return ParseOption(enum_type->mutable_options(), location); } else { - return ParseEnumConstant(enum_type->add_value()); + LocationRecorder location(enum_location, + EnumDescriptorProto::kValueFieldNumber, enum_type->value_size()); + return ParseEnumConstant(enum_type->add_value(), location); } } -bool Parser::ParseEnumConstant(EnumValueDescriptorProto* enum_value) { - RecordLocation(enum_value, DescriptorPool::ErrorCollector::NAME); - DO(ConsumeIdentifier(enum_value->mutable_name(), - "Expected enum constant name.")); +bool Parser::ParseEnumConstant(EnumValueDescriptorProto* enum_value, + const LocationRecorder& enum_value_location) { + // Parse name. + { + LocationRecorder location(enum_value_location, + EnumValueDescriptorProto::kNameFieldNumber); + location.RecordLegacyLocation( + enum_value, DescriptorPool::ErrorCollector::NAME); + DO(ConsumeIdentifier(enum_value->mutable_name(), + "Expected enum constant name.")); + } + DO(Consume("=", "Missing numeric value for enum constant.")); - bool is_negative = TryConsume("-"); - int number; - DO(ConsumeInteger(&number, "Expected integer.")); - if (is_negative) number *= -1; - enum_value->set_number(number); + // Parse value. + { + LocationRecorder location( + enum_value_location, EnumValueDescriptorProto::kNumberFieldNumber); + location.RecordLegacyLocation( + enum_value, DescriptorPool::ErrorCollector::NUMBER); + + bool is_negative = TryConsume("-"); + int number; + DO(ConsumeInteger(&number, "Expected integer.")); + if (is_negative) number *= -1; + enum_value->set_number(number); + } - DO(ParseEnumConstantOptions(enum_value)); + DO(ParseEnumConstantOptions(enum_value, enum_value_location)); DO(Consume(";")); return true; } -bool Parser::ParseEnumConstantOptions(EnumValueDescriptorProto* value) { - if (!TryConsume("[")) return true; +bool Parser::ParseEnumConstantOptions( + EnumValueDescriptorProto* value, + const LocationRecorder& enum_value_location) { + if (!LookingAt("[")) return true; + + LocationRecorder location( + enum_value_location, EnumValueDescriptorProto::kOptionsFieldNumber); + + DO(Consume("[")); do { - DO(ParseOptionAssignment(value->mutable_options())); + DO(ParseOptionAssignment(value->mutable_options(), location)); } while (TryConsume(",")); DO(Consume("]")); @@ -903,15 +1199,24 @@ bool Parser::ParseEnumConstantOptions(EnumValueDescriptorProto* value) { // ------------------------------------------------------------------- // Services -bool Parser::ParseServiceDefinition(ServiceDescriptorProto* service) { +bool Parser::ParseServiceDefinition(ServiceDescriptorProto* service, + const LocationRecorder& service_location) { DO(Consume("service")); - RecordLocation(service, DescriptorPool::ErrorCollector::NAME); - DO(ConsumeIdentifier(service->mutable_name(), "Expected service name.")); - DO(ParseServiceBlock(service)); + + { + LocationRecorder location(service_location, + ServiceDescriptorProto::kNameFieldNumber); + location.RecordLegacyLocation( + service, DescriptorPool::ErrorCollector::NAME); + DO(ConsumeIdentifier(service->mutable_name(), "Expected service name.")); + } + + DO(ParseServiceBlock(service, service_location)); return true; } -bool Parser::ParseServiceBlock(ServiceDescriptorProto* service) { +bool Parser::ParseServiceBlock(ServiceDescriptorProto* service, + const LocationRecorder& service_location) { DO(Consume("{")); while (!TryConsume("}")) { @@ -920,7 +1225,7 @@ bool Parser::ParseServiceBlock(ServiceDescriptorProto* service) { return false; } - if (!ParseServiceStatement(service)) { + if (!ParseServiceStatement(service, service_location)) { // This statement failed to parse. Skip it, but keep looping to parse // other statements. SkipStatement(); @@ -930,33 +1235,55 @@ bool Parser::ParseServiceBlock(ServiceDescriptorProto* service) { return true; } -bool Parser::ParseServiceStatement(ServiceDescriptorProto* service) { +bool Parser::ParseServiceStatement(ServiceDescriptorProto* service, + const LocationRecorder& service_location) { if (TryConsume(";")) { // empty statement; ignore return true; } else if (LookingAt("option")) { - return ParseOption(service->mutable_options()); + LocationRecorder location( + service_location, ServiceDescriptorProto::kOptionsFieldNumber); + return ParseOption(service->mutable_options(), location); } else { - return ParseServiceMethod(service->add_method()); + LocationRecorder location(service_location, + ServiceDescriptorProto::kMethodFieldNumber, service->method_size()); + return ParseServiceMethod(service->add_method(), location); } } -bool Parser::ParseServiceMethod(MethodDescriptorProto* method) { +bool Parser::ParseServiceMethod(MethodDescriptorProto* method, + const LocationRecorder& method_location) { DO(Consume("rpc")); - RecordLocation(method, DescriptorPool::ErrorCollector::NAME); - DO(ConsumeIdentifier(method->mutable_name(), "Expected method name.")); + + { + LocationRecorder location(method_location, + MethodDescriptorProto::kNameFieldNumber); + location.RecordLegacyLocation( + method, DescriptorPool::ErrorCollector::NAME); + DO(ConsumeIdentifier(method->mutable_name(), "Expected method name.")); + } // Parse input type. DO(Consume("(")); - RecordLocation(method, DescriptorPool::ErrorCollector::INPUT_TYPE); - DO(ParseUserDefinedType(method->mutable_input_type())); + { + LocationRecorder location(method_location, + MethodDescriptorProto::kInputTypeFieldNumber); + location.RecordLegacyLocation( + method, DescriptorPool::ErrorCollector::INPUT_TYPE); + DO(ParseUserDefinedType(method->mutable_input_type())); + } DO(Consume(")")); // Parse output type. DO(Consume("returns")); DO(Consume("(")); - RecordLocation(method, DescriptorPool::ErrorCollector::OUTPUT_TYPE); - DO(ParseUserDefinedType(method->mutable_output_type())); + { + LocationRecorder location(method_location, + MethodDescriptorProto::kOutputTypeFieldNumber); + location.RecordLegacyLocation( + method, DescriptorPool::ErrorCollector::OUTPUT_TYPE); + DO(ParseUserDefinedType(method->mutable_output_type())); + } DO(Consume(")")); if (TryConsume("{")) { @@ -970,7 +1297,9 @@ bool Parser::ParseServiceMethod(MethodDescriptorProto* method) { if (TryConsume(";")) { // empty statement; ignore } else { - if (!ParseOption(method->mutable_options())) { + LocationRecorder location(method_location, + MethodDescriptorProto::kOptionsFieldNumber); + if (!ParseOption(method->mutable_options(), location)) { // This statement failed to parse. Skip it, but keep looping to // parse other statements. SkipStatement(); @@ -1054,7 +1383,8 @@ bool Parser::ParseUserDefinedType(string* type_name) { // =================================================================== -bool Parser::ParsePackage(FileDescriptorProto* file) { +bool Parser::ParsePackage(FileDescriptorProto* file, + const LocationRecorder& root_location) { if (file->has_package()) { AddError("Multiple package definitions."); // Don't append the new package to the old one. Just replace it. Not @@ -1064,31 +1394,43 @@ bool Parser::ParsePackage(FileDescriptorProto* file) { DO(Consume("package")); - RecordLocation(file, DescriptorPool::ErrorCollector::NAME); + { + LocationRecorder location(root_location, + FileDescriptorProto::kPackageFieldNumber); + location.RecordLegacyLocation(file, DescriptorPool::ErrorCollector::NAME); - while (true) { - string identifier; - DO(ConsumeIdentifier(&identifier, "Expected identifier.")); - file->mutable_package()->append(identifier); - if (!TryConsume(".")) break; - file->mutable_package()->append("."); + while (true) { + string identifier; + DO(ConsumeIdentifier(&identifier, "Expected identifier.")); + file->mutable_package()->append(identifier); + if (!TryConsume(".")) break; + file->mutable_package()->append("."); + } } DO(Consume(";")); return true; } -bool Parser::ParseImport(string* import_filename) { +bool Parser::ParseImport(string* import_filename, + const LocationRecorder& root_location, + int index) { DO(Consume("import")); - DO(ConsumeString(import_filename, - "Expected a string naming the file to import.")); + { + LocationRecorder location(root_location, + FileDescriptorProto::kDependencyFieldNumber, + index); + DO(ConsumeString(import_filename, + "Expected a string naming the file to import.")); + } DO(Consume(";")); return true; } -bool Parser::ParseOption(Message* options) { +bool Parser::ParseOption(Message* options, + const LocationRecorder& options_location) { DO(Consume("option")); - DO(ParseOptionAssignment(options)); + DO(ParseOptionAssignment(options, options_location)); DO(Consume(";")); return true; } diff --git a/third_party/protobuf/src/google/protobuf/compiler/parser.h b/third_party/protobuf/src/google/protobuf/compiler/parser.h index 72c96d0..4cc90a29 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/parser.h +++ b/third_party/protobuf/src/google/protobuf/compiler/parser.h @@ -74,6 +74,9 @@ class LIBPROTOBUF_EXPORT Parser { // Optional fetaures: + // DEPRECATED: New code should use the SourceCodeInfo embedded in the + // FileDescriptorProto. + // // Requests that locations of certain definitions be recorded to the given // SourceLocationTable while parsing. This can be used to look up exact line // and column numbers for errors reported by DescriptorPool during validation. @@ -82,7 +85,7 @@ class LIBPROTOBUF_EXPORT Parser { source_location_table_ = location_table; } - // Requsets that errors be recorded to the given ErrorCollector while + // Requests that errors be recorded to the given ErrorCollector while // parsing. Set to NULL (the default) to discard error messages. void RecordErrorsTo(io::ErrorCollector* error_collector) { error_collector_ = error_collector; @@ -180,16 +183,56 @@ class LIBPROTOBUF_EXPORT Parser { // of the current token. void AddError(const string& error); - // Record the given line and column and associate it with this descriptor - // in the SourceLocationTable. - void RecordLocation(const Message* descriptor, - DescriptorPool::ErrorCollector::ErrorLocation location, - int line, int column); - - // Record the current line and column and associate it with this descriptor - // in the SourceLocationTable. - void RecordLocation(const Message* descriptor, - DescriptorPool::ErrorCollector::ErrorLocation location); + // Records a location in the SourceCodeInfo.location table (see + // descriptor.proto). We use RAII to ensure that the start and end locations + // are recorded -- the constructor records the start location and the + // destructor records the end location. Since the parser is + // recursive-descent, this works out beautifully. + class LIBPROTOBUF_EXPORT LocationRecorder { + public: + // Construct the file's "root" location. + LocationRecorder(Parser* parser); + + // Construct a location that represents a declaration nested within the + // given parent. E.g. a field's location is nested within the location + // for a message type. The parent's path will be copied, so you should + // call AddPath() only to add the path components leading from the parent + // to the child (as opposed to leading from the root to the child). + LocationRecorder(const LocationRecorder& parent); + + // Convenience constructors that call AddPath() one or two times. + LocationRecorder(const LocationRecorder& parent, int path1); + LocationRecorder(const LocationRecorder& parent, int path1, int path2); + + ~LocationRecorder(); + + // Add a path component. See SourceCodeInfo.Location.path in + // descriptor.proto. + void AddPath(int path_component); + + // By default the location is considered to start at the current token at + // the time the LocationRecorder is created. StartAt() sets the start + // location to the given token instead. + void StartAt(const io::Tokenizer::Token& token); + + // By default the location is considered to end at the previous token at + // the time the LocationRecorder is destroyed. EndAt() sets the end + // location to the given token instead. + void EndAt(const io::Tokenizer::Token& token); + + // Records the start point of this location to the SourceLocationTable that + // was passed to RecordSourceLocationsTo(), if any. SourceLocationTable + // is an older way of keeping track of source locations which is still + // used in some places. + void RecordLegacyLocation(const Message* descriptor, + DescriptorPool::ErrorCollector::ErrorLocation location); + + private: + Parser* parser_; + SourceCodeInfo::Location* location_; + + void Init(const LocationRecorder& parent); + }; // ================================================================= // Parsers for various language constructs @@ -210,50 +253,81 @@ class LIBPROTOBUF_EXPORT Parser { // makes logic much simpler for the caller. // Parse a top-level message, enum, service, etc. - bool ParseTopLevelStatement(FileDescriptorProto* file); + bool ParseTopLevelStatement(FileDescriptorProto* file, + const LocationRecorder& root_location); // Parse various language high-level language construrcts. - bool ParseMessageDefinition(DescriptorProto* message); - bool ParseEnumDefinition(EnumDescriptorProto* enum_type); - bool ParseServiceDefinition(ServiceDescriptorProto* service); - bool ParsePackage(FileDescriptorProto* file); - bool ParseImport(string* import_filename); - bool ParseOption(Message* options); + bool ParseMessageDefinition(DescriptorProto* message, + const LocationRecorder& message_location); + bool ParseEnumDefinition(EnumDescriptorProto* enum_type, + const LocationRecorder& enum_location); + bool ParseServiceDefinition(ServiceDescriptorProto* service, + const LocationRecorder& service_location); + bool ParsePackage(FileDescriptorProto* file, + const LocationRecorder& root_location); + bool ParseImport(string* import_filename, + const LocationRecorder& root_location, + int index); + bool ParseOption(Message* options, + const LocationRecorder& options_location); // These methods parse the contents of a message, enum, or service type and // add them to the given object. They consume the entire block including // the beginning and ending brace. - bool ParseMessageBlock(DescriptorProto* message); - bool ParseEnumBlock(EnumDescriptorProto* enum_type); - bool ParseServiceBlock(ServiceDescriptorProto* service); + bool ParseMessageBlock(DescriptorProto* message, + const LocationRecorder& message_location); + bool ParseEnumBlock(EnumDescriptorProto* enum_type, + const LocationRecorder& enum_location); + bool ParseServiceBlock(ServiceDescriptorProto* service, + const LocationRecorder& service_location); // Parse one statement within a message, enum, or service block, inclunding // final semicolon. - bool ParseMessageStatement(DescriptorProto* message); - bool ParseEnumStatement(EnumDescriptorProto* message); - bool ParseServiceStatement(ServiceDescriptorProto* message); + bool ParseMessageStatement(DescriptorProto* message, + const LocationRecorder& message_location); + bool ParseEnumStatement(EnumDescriptorProto* message, + const LocationRecorder& enum_location); + bool ParseServiceStatement(ServiceDescriptorProto* message, + const LocationRecorder& service_location); // Parse a field of a message. If the field is a group, its type will be // added to "messages". + // + // parent_location and location_field_number_for_nested_type are needed when + // parsing groups -- we need to generate a nested message type within the + // parent and record its location accordingly. Since the parent could be + // either a FileDescriptorProto or a DescriptorProto, we must pass in the + // correct field number to use. bool ParseMessageField(FieldDescriptorProto* field, - RepeatedPtrField<DescriptorProto>* messages); + RepeatedPtrField<DescriptorProto>* messages, + const LocationRecorder& parent_location, + int location_field_number_for_nested_type, + const LocationRecorder& field_location); // Parse an "extensions" declaration. - bool ParseExtensions(DescriptorProto* message); + bool ParseExtensions(DescriptorProto* message, + const LocationRecorder& extensions_location); - // Parse an "extend" declaration. + // Parse an "extend" declaration. (See also comments for + // ParseMessageField().) bool ParseExtend(RepeatedPtrField<FieldDescriptorProto>* extensions, - RepeatedPtrField<DescriptorProto>* messages); + RepeatedPtrField<DescriptorProto>* messages, + const LocationRecorder& parent_location, + int location_field_number_for_nested_type, + const LocationRecorder& extend_location); // Parse a single enum value within an enum block. - bool ParseEnumConstant(EnumValueDescriptorProto* enum_value); + bool ParseEnumConstant(EnumValueDescriptorProto* enum_value, + const LocationRecorder& enum_value_location); // Parse enum constant options, i.e. the list in square brackets at the end // of the enum constant value definition. - bool ParseEnumConstantOptions(EnumValueDescriptorProto* value); + bool ParseEnumConstantOptions(EnumValueDescriptorProto* value, + const LocationRecorder& enum_value_location); // Parse a single method within a service definition. - bool ParseServiceMethod(MethodDescriptorProto* method); + bool ParseServiceMethod(MethodDescriptorProto* method, + const LocationRecorder& method_location); // Parse "required", "optional", or "repeated" and fill in "label" // with the value. @@ -269,28 +343,45 @@ class LIBPROTOBUF_EXPORT Parser { // Parses field options, i.e. the stuff in square brackets at the end // of a field definition. Also parses default value. - bool ParseFieldOptions(FieldDescriptorProto* field); + bool ParseFieldOptions(FieldDescriptorProto* field, + const LocationRecorder& field_location); // Parse the "default" option. This needs special handling because its // type is the field's type. - bool ParseDefaultAssignment(FieldDescriptorProto* field); + bool ParseDefaultAssignment(FieldDescriptorProto* field, + const LocationRecorder& field_location); // Parse a single option name/value pair, e.g. "ctype = CORD". The name // identifies a field of the given Message, and the value of that field // is set to the parsed value. - bool ParseOptionAssignment(Message* options); + bool ParseOptionAssignment(Message* options, + const LocationRecorder& options_location); // Parses a single part of a multipart option name. A multipart name consists // of names separated by dots. Each name is either an identifier or a series // of identifiers separated by dots and enclosed in parentheses. E.g., // "foo.(bar.baz).qux". - bool ParseOptionNamePart(UninterpretedOption* uninterpreted_option); + bool ParseOptionNamePart(UninterpretedOption* uninterpreted_option, + const LocationRecorder& part_location); + + // Parses a string surrounded by balanced braces. Strips off the outer + // braces and stores the enclosed string in *value. + // E.g., + // { foo } *value gets 'foo' + // { foo { bar: box } } *value gets 'foo { bar: box }' + // {} *value gets '' + // + // REQUIRES: LookingAt("{") + // When finished successfully, we are looking at the first token past + // the ending brace. + bool ParseUninterpretedBlock(string* value); // ================================================================= io::Tokenizer* input_; io::ErrorCollector* error_collector_; - SourceLocationTable* source_location_table_; + SourceCodeInfo* source_code_info_; + SourceLocationTable* source_location_table_; // legacy bool had_errors_; bool require_syntax_identifier_; bool stop_after_syntax_identifier_; @@ -302,6 +393,11 @@ class LIBPROTOBUF_EXPORT Parser { // A table mapping (descriptor, ErrorLocation) pairs -- as reported by // DescriptorPool when validating descriptors -- to line and column numbers // within the original source code. +// +// This is semi-obsolete: FileDescriptorProto.source_code_info now contains +// far more complete information about source locations. However, as of this +// writing you still need to use SourceLocationTable when integrating with +// DescriptorPool. class LIBPROTOBUF_EXPORT SourceLocationTable { public: SourceLocationTable(); diff --git a/third_party/protobuf/src/google/protobuf/compiler/parser_unittest.cc b/third_party/protobuf/src/google/protobuf/compiler/parser_unittest.cc index e2262b8..156c0dc 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/parser_unittest.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/parser_unittest.cc @@ -34,6 +34,7 @@ #include <vector> #include <algorithm> +#include <map> #include <google/protobuf/compiler/parser.h> @@ -45,6 +46,7 @@ #include <google/protobuf/unittest.pb.h> #include <google/protobuf/stubs/strutil.h> #include <google/protobuf/stubs/substitute.h> +#include <google/protobuf/stubs/map-util.h> #include <google/protobuf/testing/googletest.h> #include <gtest/gtest.h> @@ -118,6 +120,9 @@ class ParserTest : public testing::Test { EXPECT_EQ(io::Tokenizer::TYPE_END, input_->current().type); ASSERT_EQ("", error_collector_.text_); + // We don't cover SourceCodeInfo in these tests. + actual.clear_source_code_info(); + // Parse the ASCII representation in order to canonicalize it. We could // just compare directly to actual.DebugString(), but that would require // that the caller precisely match the formatting that DebugString() @@ -930,6 +935,12 @@ TEST_F(ParseErrorTest, MultipleParseErrors) { "3:25: Expected \";\".\n"); } +TEST_F(ParseErrorTest, EofInAggregateValue) { + ExpectHasErrors( + "option (fileopt) = { i:100\n", + "1:0: Unexpected end of stream while parsing aggregate value.\n"); +} + // ------------------------------------------------------------------- // Enum errors @@ -1248,6 +1259,861 @@ TEST_F(ParseDecriptorDebugTest, TestAllDescriptorTypes) { } // =================================================================== +// SourceCodeInfo tests. + +// Follows a path -- as defined by SourceCodeInfo.Location.path -- from a +// message to a particular sub-field. +// * If the target is itself a message, sets *output_message to point at it, +// *output_field to NULL, and *output_index to -1. +// * Otherwise, if the target is an element of a repeated field, sets +// *output_message to the containing message, *output_field to the descriptor +// of the field, and *output_index to the index of the element. +// * Otherwise, the target is a field (possibly a repeated field, but not any +// one element). Sets *output_message to the containing message, +// *output_field to the descriptor of the field, and *output_index to -1. +// Returns true if the path was valid, false otherwise. A gTest failure is +// recorded before returning false. +bool FollowPath(const Message& root, + const int* path_begin, const int* path_end, + const Message** output_message, + const FieldDescriptor** output_field, + int* output_index) { + if (path_begin == path_end) { + // Path refers to this whole message. + *output_message = &root; + *output_field = NULL; + *output_index = -1; + return true; + } + + const Descriptor* descriptor = root.GetDescriptor(); + const Reflection* reflection = root.GetReflection(); + + const FieldDescriptor* field = descriptor->FindFieldByNumber(*path_begin); + + if (field == NULL) { + ADD_FAILURE() << descriptor->name() << " has no field number: " + << *path_begin; + return false; + } + + ++path_begin; + + if (field->is_repeated()) { + if (path_begin == path_end) { + // Path refers to the whole repeated field. + *output_message = &root; + *output_field = field; + *output_index = -1; + return true; + } + + int index = *path_begin++; + int size = reflection->FieldSize(root, field); + + if (index >= size) { + ADD_FAILURE() << descriptor->name() << "." << field->name() + << " has size " << size << ", but path contained index: " + << index; + return false; + } + + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + // Descend into child message. + const Message& child = reflection->GetRepeatedMessage(root, field, index); + return FollowPath(child, path_begin, path_end, + output_message, output_field, output_index); + } else if (path_begin == path_end) { + // Path refers to this element. + *output_message = &root; + *output_field = field; + *output_index = index; + return true; + } else { + ADD_FAILURE() << descriptor->name() << "." << field->name() + << " is not a message; cannot descend into it."; + return false; + } + } else { + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + const Message& child = reflection->GetMessage(root, field); + return FollowPath(child, path_begin, path_end, + output_message, output_field, output_index); + } else if (path_begin == path_end) { + // Path refers to this field. + *output_message = &root; + *output_field = field; + *output_index = -1; + return true; + } else { + ADD_FAILURE() << descriptor->name() << "." << field->name() + << " is not a message; cannot descend into it."; + return false; + } + } +} + +// Split some text on line breaks. The line breaks are retained in the output, +// so each line (except the last) ends with a '\n', and the lines can be +// concatenated to produce the original text. +// +// I couldn't find the proper string utility function for this. Our +// split-on-delimiter functions don't include the delimiter in the output. +void SplitLines(const string& text, vector<string>* lines) { + string::size_type pos = 0; + + while (pos != string::npos) { + string::size_type last_pos = pos; + pos = text.find_first_of('\n', pos); + if (pos != string::npos) ++pos; + lines->push_back(text.substr(last_pos, pos - last_pos)); + } +} + +// Look for the given tags in the given text and construct a span (as defined +// by SourceCodeInfo.Location.span) from them. E.g. for text like: +// /*a*/message /*b*/Foo/*c*/ {}/*d*/ +// There are four tags: "a", "b", "c", and "d". The constructed span starts +// immediately after the start tag's trailing '/' and ends immediately before +// the end tags leading '/'. +void MakeExpectedSpan(const vector<string>& lines, + const string& start_tag, const string& end_tag, + RepeatedField<int>* output) { + string start_comment = "/*" + start_tag + "*/"; + string end_comment = "/*" + end_tag + "*/"; + + int start_line = -1; + int start_column = -1; + for (int i = 0; i < lines.size(); i++) { + string::size_type pos = lines[i].find(start_comment); + if (pos != string::npos) { + start_line = i; + start_column = pos + start_comment.size(); + break; + } + } + ASSERT_NE(start_line, -1) + << "Tag \"" << start_comment << "\" not found in text."; + + int end_line = -1; + int end_column = -1; + for (int i = start_line; i < lines.size(); i++) { + string::size_type pos = lines[i].find(end_comment); + if (pos != string::npos) { + end_line = i; + end_column = pos; + break; + } + } + ASSERT_NE(end_line, -1) + << "Tag \"" << end_comment << "\" not found in text."; + + output->Add(start_line); + output->Add(start_column); + if (end_line != start_line) output->Add(end_line); + output->Add(end_column); +} + +// Check if two spans are equal. +bool CompareSpans(const RepeatedField<int>& span1, + const RepeatedField<int>& span2) { + if (span1.size() != span2.size()) return false; + for (int i = 0; i < span1.size(); i++) { + if (span1.Get(i) != span2.Get(i)) return false; + } + return true; +} + +// Test fixture for source info tests, which check that source locations are +// recorded correctly in FileDescriptorProto.source_code_info.location. +class SourceInfoTest : public ParserTest { + protected: + // The parsed file (initialized by Parse()). + FileDescriptorProto file_; + + // Parse the given text as a .proto file and populate the spans_ map with + // all the source location spans in its SourceCodeInfo table. + bool Parse(const char* text) { + SetupParser(text); + SplitLines(text, &lines_); + if (!parser_->Parse(input_.get(), &file_)) { + return false; + } + + const SourceCodeInfo& source_info = file_.source_code_info(); + for (int i = 0; i < source_info.location_size(); i++) { + const SourceCodeInfo::Location& location = source_info.location(i); + const Message* descriptor_proto = NULL; + const FieldDescriptor* field = NULL; + int index = 0; + if (!FollowPath(file_, location.path().begin(), location.path().end(), + &descriptor_proto, &field, &index)) { + return false; + } + + spans_.insert(make_pair(SpanKey(*descriptor_proto, field, index), + &location)); + } + + return true; + } + + virtual void TearDown() { + EXPECT_TRUE(spans_.empty()) + << "Forgot to call HasSpan() for:\n" + << spans_.begin()->second->DebugString(); + } + + // ----------------------------------------------------------------- + // HasSpan() checks that the span of source code delimited by the given + // tags (comments) correspond via the SourceCodeInfo table to the given + // part of the FileDescriptorProto. (If unclear, look at the actual tests; + // it should quickly become obvious.) + + bool HasSpan(const char* start_tag, const char* end_tag, + const Message& descriptor_proto) { + return HasSpan(start_tag, end_tag, descriptor_proto, NULL, -1); + } + + bool HasSpan(const char* start_tag, const char* end_tag, + const Message& descriptor_proto, const string& field_name) { + return HasSpan(start_tag, end_tag, descriptor_proto, field_name, -1); + } + + bool HasSpan(const char* start_tag, const char* end_tag, + const Message& descriptor_proto, const string& field_name, + int index) { + const FieldDescriptor* field = + descriptor_proto.GetDescriptor()->FindFieldByName(field_name); + if (field == NULL) { + ADD_FAILURE() << descriptor_proto.GetDescriptor()->name() + << " has no such field: " << field_name; + return false; + } + + return HasSpan(start_tag, end_tag, descriptor_proto, field, index); + } + + bool HasSpan(const Message& descriptor_proto) { + return HasSpan(NULL, NULL, descriptor_proto, NULL, -1); + } + + bool HasSpan(const Message& descriptor_proto, const string& field_name) { + return HasSpan(NULL, NULL, descriptor_proto, field_name, -1); + } + + bool HasSpan(const Message& descriptor_proto, const string& field_name, + int index) { + return HasSpan(NULL, NULL, descriptor_proto, field_name, index); + } + + bool HasSpan(const char* start_tag, const char* end_tag, + const Message& descriptor_proto, const FieldDescriptor* field, + int index) { + pair<SpanMap::iterator, SpanMap::iterator> range = + spans_.equal_range(SpanKey(descriptor_proto, field, index)); + + if (start_tag == NULL) { + if (range.first == range.second) { + return false; + } else { + spans_.erase(range.first); + return true; + } + } else { + RepeatedField<int> expected_span; + MakeExpectedSpan(lines_, start_tag, end_tag, &expected_span); + + for (SpanMap::iterator iter = range.first; iter != range.second; ++iter) { + if (CompareSpans(expected_span, iter->second->span())) { + spans_.erase(iter); + return true; + } + } + + return false; + } + } + + private: + struct SpanKey { + const Message* descriptor_proto; + const FieldDescriptor* field; + int index; + + inline SpanKey() {} + inline SpanKey(const Message& descriptor_proto, + const FieldDescriptor* field, + int index) + : descriptor_proto(&descriptor_proto), field(field), index(index) {} + + inline bool operator<(const SpanKey& other) const { + if (descriptor_proto < other.descriptor_proto) return true; + if (descriptor_proto > other.descriptor_proto) return false; + if (field < other.field) return true; + if (field > other.field) return false; + return index < other.index; + } + }; + + typedef multimap<SpanKey, const SourceCodeInfo::Location*> SpanMap; + SpanMap spans_; + vector<string> lines_; +}; + +TEST_F(SourceInfoTest, BasicFileDecls) { + EXPECT_TRUE(Parse( + "/*a*/syntax = \"proto2\";\n" + "package /*b*/foo.bar/*c*/;\n" + "import /*d*/\"baz.proto\"/*e*/;\n" + "import /*f*/\"qux.proto\"/*g*/;/*h*/\n" + "// comment ignored\n")); + + EXPECT_TRUE(HasSpan("a", "h", file_)); + EXPECT_TRUE(HasSpan("b", "c", file_, "package")); + EXPECT_TRUE(HasSpan("d", "e", file_, "dependency", 0)); + EXPECT_TRUE(HasSpan("f", "g", file_, "dependency", 1)); +} + +TEST_F(SourceInfoTest, Messages) { + EXPECT_TRUE(Parse( + "/*a*/message /*b*/Foo/*c*/ {}/*d*/\n" + "/*e*/message /*f*/Bar/*g*/ {}/*h*/\n")); + + EXPECT_TRUE(HasSpan("a", "d", file_.message_type(0))); + EXPECT_TRUE(HasSpan("b", "c", file_.message_type(0), "name")); + EXPECT_TRUE(HasSpan("e", "h", file_.message_type(1))); + EXPECT_TRUE(HasSpan("f", "g", file_.message_type(1), "name")); + + // Ignore these. + EXPECT_TRUE(HasSpan(file_)); +} + +TEST_F(SourceInfoTest, Fields) { + EXPECT_TRUE(Parse( + "message Foo {\n" + " /*a*/optional/*b*/ /*c*/int32/*d*/ /*e*/bar/*f*/ = /*g*/1/*h*/;/*i*/\n" + " /*j*/repeated/*k*/ /*l*/X.Y/*m*/ /*n*/baz/*o*/ = /*p*/2/*q*/;/*r*/\n" + "}\n")); + + const FieldDescriptorProto& field1 = file_.message_type(0).field(0); + const FieldDescriptorProto& field2 = file_.message_type(0).field(1); + + EXPECT_TRUE(HasSpan("a", "i", field1)); + EXPECT_TRUE(HasSpan("a", "b", field1, "label")); + EXPECT_TRUE(HasSpan("c", "d", field1, "type")); + EXPECT_TRUE(HasSpan("e", "f", field1, "name")); + EXPECT_TRUE(HasSpan("g", "h", field1, "number")); + + EXPECT_TRUE(HasSpan("j", "r", field2)); + EXPECT_TRUE(HasSpan("j", "k", field2, "label")); + EXPECT_TRUE(HasSpan("l", "m", field2, "type_name")); + EXPECT_TRUE(HasSpan("n", "o", field2, "name")); + EXPECT_TRUE(HasSpan("p", "q", field2, "number")); + + // Ignore these. + EXPECT_TRUE(HasSpan(file_)); + EXPECT_TRUE(HasSpan(file_.message_type(0))); + EXPECT_TRUE(HasSpan(file_.message_type(0), "name")); +} + +TEST_F(SourceInfoTest, Extensions) { + EXPECT_TRUE(Parse( + "/*a*/extend /*b*/Foo/*c*/ {\n" + " /*d*/optional/*e*/ int32 bar = 1;/*f*/\n" + " /*g*/repeated/*h*/ X.Y baz = 2;/*i*/\n" + "}/*j*/\n" + "/*k*/extend /*l*/Bar/*m*/ {\n" + " /*n*/optional int32 qux = 1;/*o*/\n" + "}/*p*/\n")); + + const FieldDescriptorProto& field1 = file_.extension(0); + const FieldDescriptorProto& field2 = file_.extension(1); + const FieldDescriptorProto& field3 = file_.extension(2); + + EXPECT_TRUE(HasSpan("a", "j", file_, "extension")); + EXPECT_TRUE(HasSpan("k", "p", file_, "extension")); + + EXPECT_TRUE(HasSpan("d", "f", field1)); + EXPECT_TRUE(HasSpan("d", "e", field1, "label")); + EXPECT_TRUE(HasSpan("b", "c", field1, "extendee")); + + EXPECT_TRUE(HasSpan("g", "i", field2)); + EXPECT_TRUE(HasSpan("g", "h", field2, "label")); + EXPECT_TRUE(HasSpan("b", "c", field2, "extendee")); + + EXPECT_TRUE(HasSpan("n", "o", field3)); + EXPECT_TRUE(HasSpan("l", "m", field3, "extendee")); + + // Ignore these. + EXPECT_TRUE(HasSpan(file_)); + EXPECT_TRUE(HasSpan(field1, "type")); + EXPECT_TRUE(HasSpan(field1, "name")); + EXPECT_TRUE(HasSpan(field1, "number")); + EXPECT_TRUE(HasSpan(field2, "type_name")); + EXPECT_TRUE(HasSpan(field2, "name")); + EXPECT_TRUE(HasSpan(field2, "number")); + EXPECT_TRUE(HasSpan(field3, "label")); + EXPECT_TRUE(HasSpan(field3, "type")); + EXPECT_TRUE(HasSpan(field3, "name")); + EXPECT_TRUE(HasSpan(field3, "number")); +} + +TEST_F(SourceInfoTest, NestedExtensions) { + EXPECT_TRUE(Parse( + "message Message {\n" + " /*a*/extend /*b*/Foo/*c*/ {\n" + " /*d*/optional/*e*/ int32 bar = 1;/*f*/\n" + " /*g*/repeated/*h*/ X.Y baz = 2;/*i*/\n" + " }/*j*/\n" + " /*k*/extend /*l*/Bar/*m*/ {\n" + " /*n*/optional int32 qux = 1;/*o*/\n" + " }/*p*/\n" + "}\n")); + + const FieldDescriptorProto& field1 = file_.message_type(0).extension(0); + const FieldDescriptorProto& field2 = file_.message_type(0).extension(1); + const FieldDescriptorProto& field3 = file_.message_type(0).extension(2); + + EXPECT_TRUE(HasSpan("a", "j", file_.message_type(0), "extension")); + EXPECT_TRUE(HasSpan("k", "p", file_.message_type(0), "extension")); + + EXPECT_TRUE(HasSpan("d", "f", field1)); + EXPECT_TRUE(HasSpan("d", "e", field1, "label")); + EXPECT_TRUE(HasSpan("b", "c", field1, "extendee")); + + EXPECT_TRUE(HasSpan("g", "i", field2)); + EXPECT_TRUE(HasSpan("g", "h", field2, "label")); + EXPECT_TRUE(HasSpan("b", "c", field2, "extendee")); + + EXPECT_TRUE(HasSpan("n", "o", field3)); + EXPECT_TRUE(HasSpan("l", "m", field3, "extendee")); + + // Ignore these. + EXPECT_TRUE(HasSpan(file_)); + EXPECT_TRUE(HasSpan(file_.message_type(0))); + EXPECT_TRUE(HasSpan(file_.message_type(0), "name")); + EXPECT_TRUE(HasSpan(field1, "type")); + EXPECT_TRUE(HasSpan(field1, "name")); + EXPECT_TRUE(HasSpan(field1, "number")); + EXPECT_TRUE(HasSpan(field2, "type_name")); + EXPECT_TRUE(HasSpan(field2, "name")); + EXPECT_TRUE(HasSpan(field2, "number")); + EXPECT_TRUE(HasSpan(field3, "label")); + EXPECT_TRUE(HasSpan(field3, "type")); + EXPECT_TRUE(HasSpan(field3, "name")); + EXPECT_TRUE(HasSpan(field3, "number")); +} + +TEST_F(SourceInfoTest, ExtensionRanges) { + EXPECT_TRUE(Parse( + "message Message {\n" + " /*a*/extensions /*b*/1/*c*/ to /*d*/4/*e*/, /*f*/6/*g*/;/*h*/\n" + " /*i*/extensions /*j*/8/*k*/ to /*l*/max/*m*/;/*n*/\n" + "}\n")); + + const DescriptorProto::ExtensionRange& range1 = + file_.message_type(0).extension_range(0); + const DescriptorProto::ExtensionRange& range2 = + file_.message_type(0).extension_range(1); + const DescriptorProto::ExtensionRange& range3 = + file_.message_type(0).extension_range(2); + + EXPECT_TRUE(HasSpan("a", "h", file_.message_type(0), "extension_range")); + EXPECT_TRUE(HasSpan("i", "n", file_.message_type(0), "extension_range")); + + EXPECT_TRUE(HasSpan("b", "e", range1)); + EXPECT_TRUE(HasSpan("b", "c", range1, "start")); + EXPECT_TRUE(HasSpan("d", "e", range1, "end")); + + EXPECT_TRUE(HasSpan("f", "g", range2)); + EXPECT_TRUE(HasSpan("f", "g", range2, "start")); + EXPECT_TRUE(HasSpan("f", "g", range2, "end")); + + EXPECT_TRUE(HasSpan("j", "m", range3)); + EXPECT_TRUE(HasSpan("j", "k", range3, "start")); + EXPECT_TRUE(HasSpan("l", "m", range3, "end")); + + // Ignore these. + EXPECT_TRUE(HasSpan(file_)); + EXPECT_TRUE(HasSpan(file_.message_type(0))); + EXPECT_TRUE(HasSpan(file_.message_type(0), "name")); +} + +TEST_F(SourceInfoTest, NestedMessages) { + EXPECT_TRUE(Parse( + "message Foo {\n" + " /*a*/message /*b*/Bar/*c*/ {\n" + " /*d*/message /*e*/Baz/*f*/ {}/*g*/\n" + " }/*h*/\n" + " /*i*/message /*j*/Qux/*k*/ {}/*l*/\n" + "}\n")); + + const DescriptorProto& bar = file_.message_type(0).nested_type(0); + const DescriptorProto& baz = bar.nested_type(0); + const DescriptorProto& qux = file_.message_type(0).nested_type(1); + + EXPECT_TRUE(HasSpan("a", "h", bar)); + EXPECT_TRUE(HasSpan("b", "c", bar, "name")); + EXPECT_TRUE(HasSpan("d", "g", baz)); + EXPECT_TRUE(HasSpan("e", "f", baz, "name")); + EXPECT_TRUE(HasSpan("i", "l", qux)); + EXPECT_TRUE(HasSpan("j", "k", qux, "name")); + + // Ignore these. + EXPECT_TRUE(HasSpan(file_)); + EXPECT_TRUE(HasSpan(file_.message_type(0))); + EXPECT_TRUE(HasSpan(file_.message_type(0), "name")); +} + +TEST_F(SourceInfoTest, Groups) { + EXPECT_TRUE(Parse( + "message Foo {\n" + " message Bar {}\n" + " /*a*/optional/*b*/ /*c*/group/*d*/ /*e*/Baz/*f*/ = /*g*/1/*h*/ {\n" + " /*i*/message Qux {}/*j*/\n" + " }/*k*/\n" + "}\n")); + + const DescriptorProto& bar = file_.message_type(0).nested_type(0); + const DescriptorProto& baz = file_.message_type(0).nested_type(1); + const DescriptorProto& qux = baz.nested_type(0); + const FieldDescriptorProto& field = file_.message_type(0).field(0); + + EXPECT_TRUE(HasSpan("a", "k", field)); + EXPECT_TRUE(HasSpan("a", "b", field, "label")); + EXPECT_TRUE(HasSpan("c", "d", field, "type")); + EXPECT_TRUE(HasSpan("e", "f", field, "name")); + EXPECT_TRUE(HasSpan("e", "f", field, "type_name")); + EXPECT_TRUE(HasSpan("g", "h", field, "number")); + + EXPECT_TRUE(HasSpan("a", "k", baz)); + EXPECT_TRUE(HasSpan("e", "f", baz, "name")); + EXPECT_TRUE(HasSpan("i", "j", qux)); + + // Ignore these. + EXPECT_TRUE(HasSpan(file_)); + EXPECT_TRUE(HasSpan(file_.message_type(0))); + EXPECT_TRUE(HasSpan(file_.message_type(0), "name")); + EXPECT_TRUE(HasSpan(bar)); + EXPECT_TRUE(HasSpan(bar, "name")); + EXPECT_TRUE(HasSpan(qux, "name")); +} + +TEST_F(SourceInfoTest, Enums) { + EXPECT_TRUE(Parse( + "/*a*/enum /*b*/Foo/*c*/ {}/*d*/\n" + "/*e*/enum /*f*/Bar/*g*/ {}/*h*/\n")); + + EXPECT_TRUE(HasSpan("a", "d", file_.enum_type(0))); + EXPECT_TRUE(HasSpan("b", "c", file_.enum_type(0), "name")); + EXPECT_TRUE(HasSpan("e", "h", file_.enum_type(1))); + EXPECT_TRUE(HasSpan("f", "g", file_.enum_type(1), "name")); + + // Ignore these. + EXPECT_TRUE(HasSpan(file_)); +} + +TEST_F(SourceInfoTest, EnumValues) { + EXPECT_TRUE(Parse( + "enum Foo {\n" + " /*a*/BAR/*b*/ = /*c*/1/*d*/;/*e*/\n" + " /*f*/BAZ/*g*/ = /*h*/2/*i*/;/*j*/\n" + "}")); + + const EnumValueDescriptorProto& bar = file_.enum_type(0).value(0); + const EnumValueDescriptorProto& baz = file_.enum_type(0).value(1); + + EXPECT_TRUE(HasSpan("a", "e", bar)); + EXPECT_TRUE(HasSpan("a", "b", bar, "name")); + EXPECT_TRUE(HasSpan("c", "d", bar, "number")); + EXPECT_TRUE(HasSpan("f", "j", baz)); + EXPECT_TRUE(HasSpan("f", "g", baz, "name")); + EXPECT_TRUE(HasSpan("h", "i", baz, "number")); + + // Ignore these. + EXPECT_TRUE(HasSpan(file_)); + EXPECT_TRUE(HasSpan(file_.enum_type(0))); + EXPECT_TRUE(HasSpan(file_.enum_type(0), "name")); +} + +TEST_F(SourceInfoTest, NestedEnums) { + EXPECT_TRUE(Parse( + "message Foo {\n" + " /*a*/enum /*b*/Bar/*c*/ {}/*d*/\n" + " /*e*/enum /*f*/Baz/*g*/ {}/*h*/\n" + "}\n")); + + const EnumDescriptorProto& bar = file_.message_type(0).enum_type(0); + const EnumDescriptorProto& baz = file_.message_type(0).enum_type(1); + + EXPECT_TRUE(HasSpan("a", "d", bar)); + EXPECT_TRUE(HasSpan("b", "c", bar, "name")); + EXPECT_TRUE(HasSpan("e", "h", baz)); + EXPECT_TRUE(HasSpan("f", "g", baz, "name")); + + // Ignore these. + EXPECT_TRUE(HasSpan(file_)); + EXPECT_TRUE(HasSpan(file_.message_type(0))); + EXPECT_TRUE(HasSpan(file_.message_type(0), "name")); +} + +TEST_F(SourceInfoTest, Services) { + EXPECT_TRUE(Parse( + "/*a*/service /*b*/Foo/*c*/ {}/*d*/\n" + "/*e*/service /*f*/Bar/*g*/ {}/*h*/\n")); + + EXPECT_TRUE(HasSpan("a", "d", file_.service(0))); + EXPECT_TRUE(HasSpan("b", "c", file_.service(0), "name")); + EXPECT_TRUE(HasSpan("e", "h", file_.service(1))); + EXPECT_TRUE(HasSpan("f", "g", file_.service(1), "name")); + + // Ignore these. + EXPECT_TRUE(HasSpan(file_)); +} + +TEST_F(SourceInfoTest, Methods) { + EXPECT_TRUE(Parse( + "service Foo {\n" + " /*a*/rpc /*b*/Bar/*c*/(/*d*/X/*e*/) returns(/*f*/Y/*g*/);/*h*/" + " /*i*/rpc /*j*/Baz/*k*/(/*l*/Z/*m*/) returns(/*n*/W/*o*/);/*p*/" + "}")); + + const MethodDescriptorProto& bar = file_.service(0).method(0); + const MethodDescriptorProto& baz = file_.service(0).method(1); + + EXPECT_TRUE(HasSpan("a", "h", bar)); + EXPECT_TRUE(HasSpan("b", "c", bar, "name")); + EXPECT_TRUE(HasSpan("d", "e", bar, "input_type")); + EXPECT_TRUE(HasSpan("f", "g", bar, "output_type")); + + EXPECT_TRUE(HasSpan("i", "p", baz)); + EXPECT_TRUE(HasSpan("j", "k", baz, "name")); + EXPECT_TRUE(HasSpan("l", "m", baz, "input_type")); + EXPECT_TRUE(HasSpan("n", "o", baz, "output_type")); + + // Ignore these. + EXPECT_TRUE(HasSpan(file_)); + EXPECT_TRUE(HasSpan(file_.service(0))); + EXPECT_TRUE(HasSpan(file_.service(0), "name")); +} + +TEST_F(SourceInfoTest, Options) { + EXPECT_TRUE(Parse( + "/*a*/option /*b*/foo/*c*/./*d*/(/*e*/bar.baz/*f*/)/*g*/ = " + "/*h*/123/*i*/;/*j*/\n" + "/*k*/option qux = /*l*/-123/*m*/;/*n*/\n" + "/*o*/option corge = /*p*/abc/*q*/;/*r*/\n" + "/*s*/option grault = /*t*/'blah'/*u*/;/*v*/\n" + "/*w*/option garply = /*x*/{ yadda yadda }/*y*/;/*z*/\n" + "/*0*/option waldo = /*1*/123.0/*2*/;/*3*/\n" + )); + + const UninterpretedOption& option1 = file_.options().uninterpreted_option(0); + const UninterpretedOption& option2 = file_.options().uninterpreted_option(1); + const UninterpretedOption& option3 = file_.options().uninterpreted_option(2); + const UninterpretedOption& option4 = file_.options().uninterpreted_option(3); + const UninterpretedOption& option5 = file_.options().uninterpreted_option(4); + const UninterpretedOption& option6 = file_.options().uninterpreted_option(5); + + EXPECT_TRUE(HasSpan("a", "j", file_.options())); + EXPECT_TRUE(HasSpan("b", "i", option1)); + EXPECT_TRUE(HasSpan("b", "g", option1, "name")); + EXPECT_TRUE(HasSpan("b", "c", option1.name(0))); + EXPECT_TRUE(HasSpan("b", "c", option1.name(0), "name_part")); + EXPECT_TRUE(HasSpan("d", "g", option1.name(1))); + EXPECT_TRUE(HasSpan("e", "f", option1.name(1), "name_part")); + EXPECT_TRUE(HasSpan("h", "i", option1, "positive_int_value")); + + EXPECT_TRUE(HasSpan("k", "n", file_.options())); + EXPECT_TRUE(HasSpan("l", "m", option2, "negative_int_value")); + + EXPECT_TRUE(HasSpan("o", "r", file_.options())); + EXPECT_TRUE(HasSpan("p", "q", option3, "identifier_value")); + + EXPECT_TRUE(HasSpan("s", "v", file_.options())); + EXPECT_TRUE(HasSpan("t", "u", option4, "string_value")); + + EXPECT_TRUE(HasSpan("w", "z", file_.options())); + EXPECT_TRUE(HasSpan("x", "y", option5, "aggregate_value")); + + EXPECT_TRUE(HasSpan("0", "3", file_.options())); + EXPECT_TRUE(HasSpan("1", "2", option6, "double_value")); + + // Ignore these. + EXPECT_TRUE(HasSpan(file_)); + EXPECT_TRUE(HasSpan(option2)); + EXPECT_TRUE(HasSpan(option3)); + EXPECT_TRUE(HasSpan(option4)); + EXPECT_TRUE(HasSpan(option5)); + EXPECT_TRUE(HasSpan(option6)); + EXPECT_TRUE(HasSpan(option2, "name")); + EXPECT_TRUE(HasSpan(option3, "name")); + EXPECT_TRUE(HasSpan(option4, "name")); + EXPECT_TRUE(HasSpan(option5, "name")); + EXPECT_TRUE(HasSpan(option6, "name")); + EXPECT_TRUE(HasSpan(option2.name(0))); + EXPECT_TRUE(HasSpan(option3.name(0))); + EXPECT_TRUE(HasSpan(option4.name(0))); + EXPECT_TRUE(HasSpan(option5.name(0))); + EXPECT_TRUE(HasSpan(option6.name(0))); + EXPECT_TRUE(HasSpan(option2.name(0), "name_part")); + EXPECT_TRUE(HasSpan(option3.name(0), "name_part")); + EXPECT_TRUE(HasSpan(option4.name(0), "name_part")); + EXPECT_TRUE(HasSpan(option5.name(0), "name_part")); + EXPECT_TRUE(HasSpan(option6.name(0), "name_part")); +} + +TEST_F(SourceInfoTest, ScopedOptions) { + EXPECT_TRUE(Parse( + "message Foo {\n" + " /*a*/option mopt = 1;/*b*/\n" + "}\n" + "enum Bar {\n" + " /*c*/option eopt = 1;/*d*/\n" + "}\n" + "service Baz {\n" + " /*e*/option sopt = 1;/*f*/\n" + " rpc M(X) returns(Y) {\n" + " /*g*/option mopt = 1;/*h*/\n" + " }\n" + "}\n")); + + EXPECT_TRUE(HasSpan("a", "b", file_.message_type(0).options())); + EXPECT_TRUE(HasSpan("c", "d", file_.enum_type(0).options())); + EXPECT_TRUE(HasSpan("e", "f", file_.service(0).options())); + EXPECT_TRUE(HasSpan("g", "h", file_.service(0).method(0).options())); + + // Ignore these. + EXPECT_TRUE(HasSpan(file_)); + EXPECT_TRUE(HasSpan(file_.message_type(0))); + EXPECT_TRUE(HasSpan(file_.message_type(0), "name")); + EXPECT_TRUE(HasSpan(file_.message_type(0).options() + .uninterpreted_option(0))); + EXPECT_TRUE(HasSpan(file_.message_type(0).options() + .uninterpreted_option(0), "name")); + EXPECT_TRUE(HasSpan(file_.message_type(0).options() + .uninterpreted_option(0).name(0))); + EXPECT_TRUE(HasSpan(file_.message_type(0).options() + .uninterpreted_option(0).name(0), "name_part")); + EXPECT_TRUE(HasSpan(file_.message_type(0).options() + .uninterpreted_option(0), "positive_int_value")); + EXPECT_TRUE(HasSpan(file_.enum_type(0))); + EXPECT_TRUE(HasSpan(file_.enum_type(0), "name")); + EXPECT_TRUE(HasSpan(file_.enum_type(0).options() + .uninterpreted_option(0))); + EXPECT_TRUE(HasSpan(file_.enum_type(0).options() + .uninterpreted_option(0), "name")); + EXPECT_TRUE(HasSpan(file_.enum_type(0).options() + .uninterpreted_option(0).name(0))); + EXPECT_TRUE(HasSpan(file_.enum_type(0).options() + .uninterpreted_option(0).name(0), "name_part")); + EXPECT_TRUE(HasSpan(file_.enum_type(0).options() + .uninterpreted_option(0), "positive_int_value")); + EXPECT_TRUE(HasSpan(file_.service(0))); + EXPECT_TRUE(HasSpan(file_.service(0), "name")); + EXPECT_TRUE(HasSpan(file_.service(0).method(0))); + EXPECT_TRUE(HasSpan(file_.service(0).options() + .uninterpreted_option(0))); + EXPECT_TRUE(HasSpan(file_.service(0).options() + .uninterpreted_option(0), "name")); + EXPECT_TRUE(HasSpan(file_.service(0).options() + .uninterpreted_option(0).name(0))); + EXPECT_TRUE(HasSpan(file_.service(0).options() + .uninterpreted_option(0).name(0), "name_part")); + EXPECT_TRUE(HasSpan(file_.service(0).options() + .uninterpreted_option(0), "positive_int_value")); + EXPECT_TRUE(HasSpan(file_.service(0).method(0), "name")); + EXPECT_TRUE(HasSpan(file_.service(0).method(0), "input_type")); + EXPECT_TRUE(HasSpan(file_.service(0).method(0), "output_type")); + EXPECT_TRUE(HasSpan(file_.service(0).method(0).options() + .uninterpreted_option(0))); + EXPECT_TRUE(HasSpan(file_.service(0).method(0).options() + .uninterpreted_option(0), "name")); + EXPECT_TRUE(HasSpan(file_.service(0).method(0).options() + .uninterpreted_option(0).name(0))); + EXPECT_TRUE(HasSpan(file_.service(0).method(0).options() + .uninterpreted_option(0).name(0), "name_part")); + EXPECT_TRUE(HasSpan(file_.service(0).method(0).options() + .uninterpreted_option(0), "positive_int_value")); +} + +TEST_F(SourceInfoTest, FieldOptions) { + // The actual "name = value" pairs are parsed by the same code as for + // top-level options so we won't re-test that -- just make sure that the + // syntax used for field options is understood. + EXPECT_TRUE(Parse( + "message Foo {" + " optional int32 bar = 1 " + "/*a*/[default=/*b*/123/*c*/,/*d*/opt1=123/*e*/," + "/*f*/opt2='hi'/*g*/]/*h*/;" + "}\n" + )); + + const FieldDescriptorProto& field = file_.message_type(0).field(0); + const UninterpretedOption& option1 = field.options().uninterpreted_option(0); + const UninterpretedOption& option2 = field.options().uninterpreted_option(1); + + EXPECT_TRUE(HasSpan("a", "h", field.options())); + EXPECT_TRUE(HasSpan("b", "c", field, "default_value")); + EXPECT_TRUE(HasSpan("d", "e", option1)); + EXPECT_TRUE(HasSpan("f", "g", option2)); + + // Ignore these. + EXPECT_TRUE(HasSpan(file_)); + EXPECT_TRUE(HasSpan(file_.message_type(0))); + EXPECT_TRUE(HasSpan(file_.message_type(0), "name")); + EXPECT_TRUE(HasSpan(field)); + EXPECT_TRUE(HasSpan(field, "label")); + EXPECT_TRUE(HasSpan(field, "type")); + EXPECT_TRUE(HasSpan(field, "name")); + EXPECT_TRUE(HasSpan(field, "number")); + EXPECT_TRUE(HasSpan(option1, "name")); + EXPECT_TRUE(HasSpan(option2, "name")); + EXPECT_TRUE(HasSpan(option1.name(0))); + EXPECT_TRUE(HasSpan(option2.name(0))); + EXPECT_TRUE(HasSpan(option1.name(0), "name_part")); + EXPECT_TRUE(HasSpan(option2.name(0), "name_part")); + EXPECT_TRUE(HasSpan(option1, "positive_int_value")); + EXPECT_TRUE(HasSpan(option2, "string_value")); +} + +TEST_F(SourceInfoTest, EnumValueOptions) { + // The actual "name = value" pairs are parsed by the same code as for + // top-level options so we won't re-test that -- just make sure that the + // syntax used for enum options is understood. + EXPECT_TRUE(Parse( + "enum Foo {" + " BAR = 1 /*a*/[/*b*/opt1=123/*c*/,/*d*/opt2='hi'/*e*/]/*f*/;" + "}\n" + )); + + const EnumValueDescriptorProto& value = file_.enum_type(0).value(0); + const UninterpretedOption& option1 = value.options().uninterpreted_option(0); + const UninterpretedOption& option2 = value.options().uninterpreted_option(1); + + EXPECT_TRUE(HasSpan("a", "f", value.options())); + EXPECT_TRUE(HasSpan("b", "c", option1)); + EXPECT_TRUE(HasSpan("d", "e", option2)); + + // Ignore these. + EXPECT_TRUE(HasSpan(file_)); + EXPECT_TRUE(HasSpan(file_.enum_type(0))); + EXPECT_TRUE(HasSpan(file_.enum_type(0), "name")); + EXPECT_TRUE(HasSpan(value)); + EXPECT_TRUE(HasSpan(value, "name")); + EXPECT_TRUE(HasSpan(value, "number")); + EXPECT_TRUE(HasSpan(option1, "name")); + EXPECT_TRUE(HasSpan(option2, "name")); + EXPECT_TRUE(HasSpan(option1.name(0))); + EXPECT_TRUE(HasSpan(option2.name(0))); + EXPECT_TRUE(HasSpan(option1.name(0), "name_part")); + EXPECT_TRUE(HasSpan(option2.name(0), "name_part")); + EXPECT_TRUE(HasSpan(option1, "positive_int_value")); + EXPECT_TRUE(HasSpan(option2, "string_value")); +} + +// =================================================================== } // anonymous namespace diff --git a/third_party/protobuf/src/google/protobuf/compiler/plugin.cc b/third_party/protobuf/src/google/protobuf/compiler/plugin.cc index a4aedaf..727f942 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/plugin.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/plugin.cc @@ -59,13 +59,15 @@ namespace google { namespace protobuf { namespace compiler { -class GeneratorResponseOutputDirectory : public OutputDirectory { +class GeneratorResponseContext : public GeneratorContext { public: - GeneratorResponseOutputDirectory(CodeGeneratorResponse* response) - : response_(response) {} - virtual ~GeneratorResponseOutputDirectory() {} + GeneratorResponseContext(CodeGeneratorResponse* response, + const vector<const FileDescriptor*>& parsed_files) + : response_(response), + parsed_files_(parsed_files) {} + virtual ~GeneratorResponseContext() {} - // implements OutputDirectory -------------------------------------- + // implements GeneratorContext -------------------------------------- virtual io::ZeroCopyOutputStream* Open(const string& filename) { CodeGeneratorResponse::File* file = response_->add_file(); @@ -81,8 +83,13 @@ class GeneratorResponseOutputDirectory : public OutputDirectory { return new io::StringOutputStream(file->mutable_content()); } + void ListParsedFiles(vector<const FileDescriptor*>* output) { + *output = parsed_files_; + } + private: CodeGeneratorResponse* response_; + const vector<const FileDescriptor*>& parsed_files_; }; int PluginMain(int argc, char* argv[], const CodeGenerator* generator) { @@ -112,22 +119,26 @@ int PluginMain(int argc, char* argv[], const CodeGenerator* generator) { } } - CodeGeneratorResponse response; - GeneratorResponseOutputDirectory output_directory(&response); - + vector<const FileDescriptor*> parsed_files; for (int i = 0; i < request.file_to_generate_size(); i++) { - const FileDescriptor* file = - pool.FindFileByName(request.file_to_generate(i)); - if (file == NULL) { + parsed_files.push_back(pool.FindFileByName(request.file_to_generate(i))); + if (parsed_files.back() == NULL) { cerr << argv[0] << ": protoc asked plugin to generate a file but " "did not provide a descriptor for the file: " << request.file_to_generate(i) << endl; return 1; } + } + + CodeGeneratorResponse response; + GeneratorResponseContext context(&response, parsed_files); + + for (int i = 0; i < parsed_files.size(); i++) { + const FileDescriptor* file = parsed_files[i]; string error; bool succeeded = generator->Generate( - file, request.parameter(), &output_directory, &error); + file, request.parameter(), &context, &error); if (!succeeded && error.empty()) { error = "Code generator returned false but provided no error " diff --git a/third_party/protobuf/src/google/protobuf/compiler/plugin.h b/third_party/protobuf/src/google/protobuf/compiler/plugin.h index 7c40333..64dfb1d 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/plugin.h +++ b/third_party/protobuf/src/google/protobuf/compiler/plugin.h @@ -64,7 +64,7 @@ namespace compiler { class CodeGenerator; // code_generator.h // Implements main() for a protoc plugin exposing the given code generator. -LIBPROTOC_EXPORT int PluginMain(int argc, char* argv[], const CodeGenerator* generator); +int PluginMain(int argc, char* argv[], const CodeGenerator* generator); } // namespace compiler } // namespace protobuf diff --git a/third_party/protobuf/src/google/protobuf/compiler/plugin.pb.cc b/third_party/protobuf/src/google/protobuf/compiler/plugin.pb.cc index 62e7829f..75b5ffb 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/plugin.pb.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/plugin.pb.cc @@ -158,7 +158,6 @@ struct StaticDescriptorInitializer_google_2fprotobuf_2fcompiler_2fplugin_2eproto // =================================================================== -const ::std::string CodeGeneratorRequest::_default_parameter_; #ifndef _MSC_VER const int CodeGeneratorRequest::kFileToGenerateFieldNumber; const int CodeGeneratorRequest::kParameterFieldNumber; @@ -181,7 +180,7 @@ CodeGeneratorRequest::CodeGeneratorRequest(const CodeGeneratorRequest& from) void CodeGeneratorRequest::SharedCtor() { _cached_size_ = 0; - parameter_ = const_cast< ::std::string*>(&_default_parameter_); + parameter_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); ::memset(_has_bits_, 0, sizeof(_has_bits_)); } @@ -190,7 +189,7 @@ CodeGeneratorRequest::~CodeGeneratorRequest() { } void CodeGeneratorRequest::SharedDtor() { - if (parameter_ != &_default_parameter_) { + if (parameter_ != &::google::protobuf::internal::kEmptyString) { delete parameter_; } if (this != default_instance_) { @@ -219,8 +218,8 @@ CodeGeneratorRequest* CodeGeneratorRequest::New() const { void CodeGeneratorRequest::Clear() { if (_has_bits_[1 / 32] & (0xffu << (1 % 32))) { - if (_has_bit(1)) { - if (parameter_ != &_default_parameter_) { + if (has_parameter()) { + if (parameter_ != &::google::protobuf::internal::kEmptyString) { parameter_->clear(); } } @@ -314,7 +313,7 @@ void CodeGeneratorRequest::SerializeWithCachedSizes( } // optional string parameter = 2; - if (_has_bit(1)) { + if (has_parameter()) { ::google::protobuf::internal::WireFormat::VerifyUTF8String( this->parameter().data(), this->parameter().length(), ::google::protobuf::internal::WireFormat::SERIALIZE); @@ -346,7 +345,7 @@ void CodeGeneratorRequest::SerializeWithCachedSizes( } // optional string parameter = 2; - if (_has_bit(1)) { + if (has_parameter()) { ::google::protobuf::internal::WireFormat::VerifyUTF8String( this->parameter().data(), this->parameter().length(), ::google::protobuf::internal::WireFormat::SERIALIZE); @@ -424,7 +423,7 @@ void CodeGeneratorRequest::MergeFrom(const CodeGeneratorRequest& from) { file_to_generate_.MergeFrom(from.file_to_generate_); proto_file_.MergeFrom(from.proto_file_); if (from._has_bits_[1 / 32] & (0xffu << (1 % 32))) { - if (from._has_bit(1)) { + if (from.has_parameter()) { set_parameter(from.parameter()); } } @@ -473,9 +472,6 @@ void CodeGeneratorRequest::Swap(CodeGeneratorRequest* other) { // =================================================================== -const ::std::string CodeGeneratorResponse_File::_default_name_; -const ::std::string CodeGeneratorResponse_File::_default_insertion_point_; -const ::std::string CodeGeneratorResponse_File::_default_content_; #ifndef _MSC_VER const int CodeGeneratorResponse_File::kNameFieldNumber; const int CodeGeneratorResponse_File::kInsertionPointFieldNumber; @@ -498,9 +494,9 @@ CodeGeneratorResponse_File::CodeGeneratorResponse_File(const CodeGeneratorRespon void CodeGeneratorResponse_File::SharedCtor() { _cached_size_ = 0; - name_ = const_cast< ::std::string*>(&_default_name_); - insertion_point_ = const_cast< ::std::string*>(&_default_insertion_point_); - content_ = const_cast< ::std::string*>(&_default_content_); + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + insertion_point_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + content_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); ::memset(_has_bits_, 0, sizeof(_has_bits_)); } @@ -509,13 +505,13 @@ CodeGeneratorResponse_File::~CodeGeneratorResponse_File() { } void CodeGeneratorResponse_File::SharedDtor() { - if (name_ != &_default_name_) { + if (name_ != &::google::protobuf::internal::kEmptyString) { delete name_; } - if (insertion_point_ != &_default_insertion_point_) { + if (insertion_point_ != &::google::protobuf::internal::kEmptyString) { delete insertion_point_; } - if (content_ != &_default_content_) { + if (content_ != &::google::protobuf::internal::kEmptyString) { delete content_; } if (this != default_instance_) { @@ -544,18 +540,18 @@ CodeGeneratorResponse_File* CodeGeneratorResponse_File::New() const { void CodeGeneratorResponse_File::Clear() { if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (_has_bit(0)) { - if (name_ != &_default_name_) { + if (has_name()) { + if (name_ != &::google::protobuf::internal::kEmptyString) { name_->clear(); } } - if (_has_bit(1)) { - if (insertion_point_ != &_default_insertion_point_) { + if (has_insertion_point()) { + if (insertion_point_ != &::google::protobuf::internal::kEmptyString) { insertion_point_->clear(); } } - if (_has_bit(2)) { - if (content_ != &_default_content_) { + if (has_content()) { + if (content_ != &::google::protobuf::internal::kEmptyString) { content_->clear(); } } @@ -638,7 +634,7 @@ bool CodeGeneratorResponse_File::MergePartialFromCodedStream( void CodeGeneratorResponse_File::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // optional string name = 1; - if (_has_bit(0)) { + if (has_name()) { ::google::protobuf::internal::WireFormat::VerifyUTF8String( this->name().data(), this->name().length(), ::google::protobuf::internal::WireFormat::SERIALIZE); @@ -647,7 +643,7 @@ void CodeGeneratorResponse_File::SerializeWithCachedSizes( } // optional string insertion_point = 2; - if (_has_bit(1)) { + if (has_insertion_point()) { ::google::protobuf::internal::WireFormat::VerifyUTF8String( this->insertion_point().data(), this->insertion_point().length(), ::google::protobuf::internal::WireFormat::SERIALIZE); @@ -656,7 +652,7 @@ void CodeGeneratorResponse_File::SerializeWithCachedSizes( } // optional string content = 15; - if (_has_bit(2)) { + if (has_content()) { ::google::protobuf::internal::WireFormat::VerifyUTF8String( this->content().data(), this->content().length(), ::google::protobuf::internal::WireFormat::SERIALIZE); @@ -673,7 +669,7 @@ void CodeGeneratorResponse_File::SerializeWithCachedSizes( ::google::protobuf::uint8* CodeGeneratorResponse_File::SerializeWithCachedSizesToArray( ::google::protobuf::uint8* target) const { // optional string name = 1; - if (_has_bit(0)) { + if (has_name()) { ::google::protobuf::internal::WireFormat::VerifyUTF8String( this->name().data(), this->name().length(), ::google::protobuf::internal::WireFormat::SERIALIZE); @@ -683,7 +679,7 @@ void CodeGeneratorResponse_File::SerializeWithCachedSizes( } // optional string insertion_point = 2; - if (_has_bit(1)) { + if (has_insertion_point()) { ::google::protobuf::internal::WireFormat::VerifyUTF8String( this->insertion_point().data(), this->insertion_point().length(), ::google::protobuf::internal::WireFormat::SERIALIZE); @@ -693,7 +689,7 @@ void CodeGeneratorResponse_File::SerializeWithCachedSizes( } // optional string content = 15; - if (_has_bit(2)) { + if (has_content()) { ::google::protobuf::internal::WireFormat::VerifyUTF8String( this->content().data(), this->content().length(), ::google::protobuf::internal::WireFormat::SERIALIZE); @@ -761,13 +757,13 @@ void CodeGeneratorResponse_File::MergeFrom(const ::google::protobuf::Message& fr void CodeGeneratorResponse_File::MergeFrom(const CodeGeneratorResponse_File& from) { GOOGLE_CHECK_NE(&from, this); if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (from._has_bit(0)) { + if (from.has_name()) { set_name(from.name()); } - if (from._has_bit(1)) { + if (from.has_insertion_point()) { set_insertion_point(from.insertion_point()); } - if (from._has_bit(2)) { + if (from.has_content()) { set_content(from.content()); } } @@ -813,7 +809,6 @@ void CodeGeneratorResponse_File::Swap(CodeGeneratorResponse_File* other) { // ------------------------------------------------------------------- -const ::std::string CodeGeneratorResponse::_default_error_; #ifndef _MSC_VER const int CodeGeneratorResponse::kErrorFieldNumber; const int CodeGeneratorResponse::kFileFieldNumber; @@ -835,7 +830,7 @@ CodeGeneratorResponse::CodeGeneratorResponse(const CodeGeneratorResponse& from) void CodeGeneratorResponse::SharedCtor() { _cached_size_ = 0; - error_ = const_cast< ::std::string*>(&_default_error_); + error_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); ::memset(_has_bits_, 0, sizeof(_has_bits_)); } @@ -844,7 +839,7 @@ CodeGeneratorResponse::~CodeGeneratorResponse() { } void CodeGeneratorResponse::SharedDtor() { - if (error_ != &_default_error_) { + if (error_ != &::google::protobuf::internal::kEmptyString) { delete error_; } if (this != default_instance_) { @@ -873,8 +868,8 @@ CodeGeneratorResponse* CodeGeneratorResponse::New() const { void CodeGeneratorResponse::Clear() { if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (_has_bit(0)) { - if (error_ != &_default_error_) { + if (has_error()) { + if (error_ != &::google::protobuf::internal::kEmptyString) { error_->clear(); } } @@ -939,7 +934,7 @@ bool CodeGeneratorResponse::MergePartialFromCodedStream( void CodeGeneratorResponse::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // optional string error = 1; - if (_has_bit(0)) { + if (has_error()) { ::google::protobuf::internal::WireFormat::VerifyUTF8String( this->error().data(), this->error().length(), ::google::protobuf::internal::WireFormat::SERIALIZE); @@ -962,7 +957,7 @@ void CodeGeneratorResponse::SerializeWithCachedSizes( ::google::protobuf::uint8* CodeGeneratorResponse::SerializeWithCachedSizesToArray( ::google::protobuf::uint8* target) const { // optional string error = 1; - if (_has_bit(0)) { + if (has_error()) { ::google::protobuf::internal::WireFormat::VerifyUTF8String( this->error().data(), this->error().length(), ::google::protobuf::internal::WireFormat::SERIALIZE); @@ -1032,7 +1027,7 @@ void CodeGeneratorResponse::MergeFrom(const CodeGeneratorResponse& from) { GOOGLE_CHECK_NE(&from, this); file_.MergeFrom(from.file_); if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (from._has_bit(0)) { + if (from.has_error()) { set_error(from.error()); } } diff --git a/third_party/protobuf/src/google/protobuf/compiler/plugin.pb.h b/third_party/protobuf/src/google/protobuf/compiler/plugin.pb.h index bd6bf63..0e7ad1d 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/plugin.pb.h +++ b/third_party/protobuf/src/google/protobuf/compiler/plugin.pb.h @@ -8,12 +8,12 @@ #include <google/protobuf/stubs/common.h> -#if GOOGLE_PROTOBUF_VERSION < 2003000 +#if GOOGLE_PROTOBUF_VERSION < 2004000 #error This file was generated by a newer version of protoc which is #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 2003001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#if 2004000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc. @@ -22,6 +22,7 @@ #include <google/protobuf/generated_message_util.h> #include <google/protobuf/repeated_field.h> #include <google/protobuf/extension_set.h> +#include <google/protobuf/unknown_field_set.h> #include <google/protobuf/generated_message_reflection.h> #include "google/protobuf/descriptor.pb.h" // @@protoc_insertion_point(includes) @@ -120,6 +121,7 @@ class LIBPROTOC_EXPORT CodeGeneratorRequest : public ::google::protobuf::Message inline void set_parameter(const char* value); inline void set_parameter(const char* value, size_t size); inline ::std::string* mutable_parameter(); + inline ::std::string* release_parameter(); // repeated .google.protobuf.FileDescriptorProto proto_file = 15; inline int proto_file_size() const; @@ -135,29 +137,21 @@ class LIBPROTOC_EXPORT CodeGeneratorRequest : public ::google::protobuf::Message // @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorRequest) private: + inline void set_has_parameter(); + inline void clear_has_parameter(); + ::google::protobuf::UnknownFieldSet _unknown_fields_; - mutable int _cached_size_; ::google::protobuf::RepeatedPtrField< ::std::string> file_to_generate_; ::std::string* parameter_; - static const ::std::string _default_parameter_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto > proto_file_; - friend void LIBPROTOC_EXPORT protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); - friend void protobuf_AssignDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); - friend void protobuf_ShutdownFile_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); + mutable int _cached_size_; ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32]; - // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? - inline bool _has_bit(int index) const { - return (_has_bits_[index / 32] & (1u << (index % 32))) != 0; - } - inline void _set_bit(int index) { - _has_bits_[index / 32] |= (1u << (index % 32)); - } - inline void _clear_bit(int index) { - _has_bits_[index / 32] &= ~(1u << (index % 32)); - } + friend void LIBPROTOC_EXPORT protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); void InitAsDefaultInstance(); static CodeGeneratorRequest* default_instance_; @@ -227,6 +221,7 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse_File : public ::google::protobuf::M inline void set_name(const char* value); inline void set_name(const char* value, size_t size); inline ::std::string* mutable_name(); + inline ::std::string* release_name(); // optional string insertion_point = 2; inline bool has_insertion_point() const; @@ -237,6 +232,7 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse_File : public ::google::protobuf::M inline void set_insertion_point(const char* value); inline void set_insertion_point(const char* value, size_t size); inline ::std::string* mutable_insertion_point(); + inline ::std::string* release_insertion_point(); // optional string content = 15; inline bool has_content() const; @@ -247,34 +243,29 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse_File : public ::google::protobuf::M inline void set_content(const char* value); inline void set_content(const char* value, size_t size); inline ::std::string* mutable_content(); + inline ::std::string* release_content(); // @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorResponse.File) private: + inline void set_has_name(); + inline void clear_has_name(); + inline void set_has_insertion_point(); + inline void clear_has_insertion_point(); + inline void set_has_content(); + inline void clear_has_content(); + ::google::protobuf::UnknownFieldSet _unknown_fields_; - mutable int _cached_size_; ::std::string* name_; - static const ::std::string _default_name_; ::std::string* insertion_point_; - static const ::std::string _default_insertion_point_; ::std::string* content_; - static const ::std::string _default_content_; - friend void LIBPROTOC_EXPORT protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); - friend void protobuf_AssignDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); - friend void protobuf_ShutdownFile_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); + mutable int _cached_size_; ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32]; - // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? - inline bool _has_bit(int index) const { - return (_has_bits_[index / 32] & (1u << (index % 32))) != 0; - } - inline void _set_bit(int index) { - _has_bits_[index / 32] |= (1u << (index % 32)); - } - inline void _clear_bit(int index) { - _has_bits_[index / 32] &= ~(1u << (index % 32)); - } + friend void LIBPROTOC_EXPORT protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); void InitAsDefaultInstance(); static CodeGeneratorResponse_File* default_instance_; @@ -346,6 +337,7 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse : public ::google::protobuf::Messag inline void set_error(const char* value); inline void set_error(const char* value, size_t size); inline ::std::string* mutable_error(); + inline ::std::string* release_error(); // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; inline int file_size() const; @@ -361,28 +353,20 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse : public ::google::protobuf::Messag // @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorResponse) private: + inline void set_has_error(); + inline void clear_has_error(); + ::google::protobuf::UnknownFieldSet _unknown_fields_; - mutable int _cached_size_; ::std::string* error_; - static const ::std::string _default_error_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File > file_; - friend void LIBPROTOC_EXPORT protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); - friend void protobuf_AssignDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); - friend void protobuf_ShutdownFile_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); + mutable int _cached_size_; ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; - // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? - inline bool _has_bit(int index) const { - return (_has_bits_[index / 32] & (1u << (index % 32))) != 0; - } - inline void _set_bit(int index) { - _has_bits_[index / 32] |= (1u << (index % 32)); - } - inline void _clear_bit(int index) { - _has_bits_[index / 32] &= ~(1u << (index % 32)); - } + friend void LIBPROTOC_EXPORT protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fcompiler_2fplugin_2eproto(); void InitAsDefaultInstance(); static CodeGeneratorResponse* default_instance_; @@ -440,45 +424,61 @@ CodeGeneratorRequest::mutable_file_to_generate() { // optional string parameter = 2; inline bool CodeGeneratorRequest::has_parameter() const { - return _has_bit(1); + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void CodeGeneratorRequest::set_has_parameter() { + _has_bits_[0] |= 0x00000002u; +} +inline void CodeGeneratorRequest::clear_has_parameter() { + _has_bits_[0] &= ~0x00000002u; } inline void CodeGeneratorRequest::clear_parameter() { - if (parameter_ != &_default_parameter_) { + if (parameter_ != &::google::protobuf::internal::kEmptyString) { parameter_->clear(); } - _clear_bit(1); + clear_has_parameter(); } inline const ::std::string& CodeGeneratorRequest::parameter() const { return *parameter_; } inline void CodeGeneratorRequest::set_parameter(const ::std::string& value) { - _set_bit(1); - if (parameter_ == &_default_parameter_) { + set_has_parameter(); + if (parameter_ == &::google::protobuf::internal::kEmptyString) { parameter_ = new ::std::string; } parameter_->assign(value); } inline void CodeGeneratorRequest::set_parameter(const char* value) { - _set_bit(1); - if (parameter_ == &_default_parameter_) { + set_has_parameter(); + if (parameter_ == &::google::protobuf::internal::kEmptyString) { parameter_ = new ::std::string; } parameter_->assign(value); } inline void CodeGeneratorRequest::set_parameter(const char* value, size_t size) { - _set_bit(1); - if (parameter_ == &_default_parameter_) { + set_has_parameter(); + if (parameter_ == &::google::protobuf::internal::kEmptyString) { parameter_ = new ::std::string; } parameter_->assign(reinterpret_cast<const char*>(value), size); } inline ::std::string* CodeGeneratorRequest::mutable_parameter() { - _set_bit(1); - if (parameter_ == &_default_parameter_) { + set_has_parameter(); + if (parameter_ == &::google::protobuf::internal::kEmptyString) { parameter_ = new ::std::string; } return parameter_; } +inline ::std::string* CodeGeneratorRequest::release_parameter() { + clear_has_parameter(); + if (parameter_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = parameter_; + parameter_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} // repeated .google.protobuf.FileDescriptorProto proto_file = 15; inline int CodeGeneratorRequest::proto_file_size() const { @@ -511,129 +511,177 @@ CodeGeneratorRequest::mutable_proto_file() { // optional string name = 1; inline bool CodeGeneratorResponse_File::has_name() const { - return _has_bit(0); + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void CodeGeneratorResponse_File::set_has_name() { + _has_bits_[0] |= 0x00000001u; +} +inline void CodeGeneratorResponse_File::clear_has_name() { + _has_bits_[0] &= ~0x00000001u; } inline void CodeGeneratorResponse_File::clear_name() { - if (name_ != &_default_name_) { + if (name_ != &::google::protobuf::internal::kEmptyString) { name_->clear(); } - _clear_bit(0); + clear_has_name(); } inline const ::std::string& CodeGeneratorResponse_File::name() const { return *name_; } inline void CodeGeneratorResponse_File::set_name(const ::std::string& value) { - _set_bit(0); - if (name_ == &_default_name_) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { name_ = new ::std::string; } name_->assign(value); } inline void CodeGeneratorResponse_File::set_name(const char* value) { - _set_bit(0); - if (name_ == &_default_name_) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { name_ = new ::std::string; } name_->assign(value); } inline void CodeGeneratorResponse_File::set_name(const char* value, size_t size) { - _set_bit(0); - if (name_ == &_default_name_) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { name_ = new ::std::string; } name_->assign(reinterpret_cast<const char*>(value), size); } inline ::std::string* CodeGeneratorResponse_File::mutable_name() { - _set_bit(0); - if (name_ == &_default_name_) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { name_ = new ::std::string; } return name_; } +inline ::std::string* CodeGeneratorResponse_File::release_name() { + clear_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = name_; + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} // optional string insertion_point = 2; inline bool CodeGeneratorResponse_File::has_insertion_point() const { - return _has_bit(1); + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void CodeGeneratorResponse_File::set_has_insertion_point() { + _has_bits_[0] |= 0x00000002u; +} +inline void CodeGeneratorResponse_File::clear_has_insertion_point() { + _has_bits_[0] &= ~0x00000002u; } inline void CodeGeneratorResponse_File::clear_insertion_point() { - if (insertion_point_ != &_default_insertion_point_) { + if (insertion_point_ != &::google::protobuf::internal::kEmptyString) { insertion_point_->clear(); } - _clear_bit(1); + clear_has_insertion_point(); } inline const ::std::string& CodeGeneratorResponse_File::insertion_point() const { return *insertion_point_; } inline void CodeGeneratorResponse_File::set_insertion_point(const ::std::string& value) { - _set_bit(1); - if (insertion_point_ == &_default_insertion_point_) { + set_has_insertion_point(); + if (insertion_point_ == &::google::protobuf::internal::kEmptyString) { insertion_point_ = new ::std::string; } insertion_point_->assign(value); } inline void CodeGeneratorResponse_File::set_insertion_point(const char* value) { - _set_bit(1); - if (insertion_point_ == &_default_insertion_point_) { + set_has_insertion_point(); + if (insertion_point_ == &::google::protobuf::internal::kEmptyString) { insertion_point_ = new ::std::string; } insertion_point_->assign(value); } inline void CodeGeneratorResponse_File::set_insertion_point(const char* value, size_t size) { - _set_bit(1); - if (insertion_point_ == &_default_insertion_point_) { + set_has_insertion_point(); + if (insertion_point_ == &::google::protobuf::internal::kEmptyString) { insertion_point_ = new ::std::string; } insertion_point_->assign(reinterpret_cast<const char*>(value), size); } inline ::std::string* CodeGeneratorResponse_File::mutable_insertion_point() { - _set_bit(1); - if (insertion_point_ == &_default_insertion_point_) { + set_has_insertion_point(); + if (insertion_point_ == &::google::protobuf::internal::kEmptyString) { insertion_point_ = new ::std::string; } return insertion_point_; } +inline ::std::string* CodeGeneratorResponse_File::release_insertion_point() { + clear_has_insertion_point(); + if (insertion_point_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = insertion_point_; + insertion_point_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} // optional string content = 15; inline bool CodeGeneratorResponse_File::has_content() const { - return _has_bit(2); + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void CodeGeneratorResponse_File::set_has_content() { + _has_bits_[0] |= 0x00000004u; +} +inline void CodeGeneratorResponse_File::clear_has_content() { + _has_bits_[0] &= ~0x00000004u; } inline void CodeGeneratorResponse_File::clear_content() { - if (content_ != &_default_content_) { + if (content_ != &::google::protobuf::internal::kEmptyString) { content_->clear(); } - _clear_bit(2); + clear_has_content(); } inline const ::std::string& CodeGeneratorResponse_File::content() const { return *content_; } inline void CodeGeneratorResponse_File::set_content(const ::std::string& value) { - _set_bit(2); - if (content_ == &_default_content_) { + set_has_content(); + if (content_ == &::google::protobuf::internal::kEmptyString) { content_ = new ::std::string; } content_->assign(value); } inline void CodeGeneratorResponse_File::set_content(const char* value) { - _set_bit(2); - if (content_ == &_default_content_) { + set_has_content(); + if (content_ == &::google::protobuf::internal::kEmptyString) { content_ = new ::std::string; } content_->assign(value); } inline void CodeGeneratorResponse_File::set_content(const char* value, size_t size) { - _set_bit(2); - if (content_ == &_default_content_) { + set_has_content(); + if (content_ == &::google::protobuf::internal::kEmptyString) { content_ = new ::std::string; } content_->assign(reinterpret_cast<const char*>(value), size); } inline ::std::string* CodeGeneratorResponse_File::mutable_content() { - _set_bit(2); - if (content_ == &_default_content_) { + set_has_content(); + if (content_ == &::google::protobuf::internal::kEmptyString) { content_ = new ::std::string; } return content_; } +inline ::std::string* CodeGeneratorResponse_File::release_content() { + clear_has_content(); + if (content_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = content_; + content_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} // ------------------------------------------------------------------- @@ -641,45 +689,61 @@ inline ::std::string* CodeGeneratorResponse_File::mutable_content() { // optional string error = 1; inline bool CodeGeneratorResponse::has_error() const { - return _has_bit(0); + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void CodeGeneratorResponse::set_has_error() { + _has_bits_[0] |= 0x00000001u; +} +inline void CodeGeneratorResponse::clear_has_error() { + _has_bits_[0] &= ~0x00000001u; } inline void CodeGeneratorResponse::clear_error() { - if (error_ != &_default_error_) { + if (error_ != &::google::protobuf::internal::kEmptyString) { error_->clear(); } - _clear_bit(0); + clear_has_error(); } inline const ::std::string& CodeGeneratorResponse::error() const { return *error_; } inline void CodeGeneratorResponse::set_error(const ::std::string& value) { - _set_bit(0); - if (error_ == &_default_error_) { + set_has_error(); + if (error_ == &::google::protobuf::internal::kEmptyString) { error_ = new ::std::string; } error_->assign(value); } inline void CodeGeneratorResponse::set_error(const char* value) { - _set_bit(0); - if (error_ == &_default_error_) { + set_has_error(); + if (error_ == &::google::protobuf::internal::kEmptyString) { error_ = new ::std::string; } error_->assign(value); } inline void CodeGeneratorResponse::set_error(const char* value, size_t size) { - _set_bit(0); - if (error_ == &_default_error_) { + set_has_error(); + if (error_ == &::google::protobuf::internal::kEmptyString) { error_ = new ::std::string; } error_->assign(reinterpret_cast<const char*>(value), size); } inline ::std::string* CodeGeneratorResponse::mutable_error() { - _set_bit(0); - if (error_ == &_default_error_) { + set_has_error(); + if (error_ == &::google::protobuf::internal::kEmptyString) { error_ = new ::std::string; } return error_; } +inline ::std::string* CodeGeneratorResponse::release_error() { + clear_has_error(); + if (error_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = error_; + error_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; inline int CodeGeneratorResponse::file_size() const { diff --git a/third_party/protobuf/src/google/protobuf/compiler/plugin.proto b/third_party/protobuf/src/google/protobuf/compiler/plugin.proto index 4e928b0..651ed10 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/plugin.proto +++ b/third_party/protobuf/src/google/protobuf/compiler/plugin.proto @@ -131,7 +131,7 @@ message CodeGeneratorResponse { // in order to work correctly in that context. // // The code generator that generates the initial file and the one which - // inserts into it must both run as part of a single invocatino of protoc. + // inserts into it must both run as part of a single invocation of protoc. // Code generators are executed in the order in which they appear on the // command line. // diff --git a/third_party/protobuf/src/google/protobuf/compiler/python/python_generator.cc b/third_party/protobuf/src/google/protobuf/compiler/python/python_generator.cc index fae83a3..9b10937 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/python/python_generator.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/python/python_generator.cc @@ -230,7 +230,7 @@ Generator::~Generator() { bool Generator::Generate(const FileDescriptor* file, const string& parameter, - OutputDirectory* output_directory, + GeneratorContext* context, string* error) const { // Completely serialize all Generate() calls on this instance. The @@ -252,20 +252,18 @@ bool Generator::Generate(const FileDescriptor* file, fdp.SerializeToString(&file_descriptor_serialized_); - scoped_ptr<io::ZeroCopyOutputStream> output(output_directory->Open(filename)); + scoped_ptr<io::ZeroCopyOutputStream> output(context->Open(filename)); GOOGLE_CHECK(output.get()); io::Printer printer(output.get(), '$'); printer_ = &printer; PrintTopBoilerplate(printer_, file_, GeneratingDescriptorProto()); + PrintImports(); PrintFileDescriptor(); PrintTopLevelEnums(); PrintTopLevelExtensions(); PrintAllNestedEnumsInFile(); PrintMessageDescriptors(); - // We have to print the imports after the descriptors, so that mutually - // recursive protos in separate files can successfully reference each other. - PrintImports(); FixForeignFieldsInDescriptors(); PrintMessages(); // We have to fix up the extensions after the message classes themselves, @@ -377,7 +375,7 @@ void Generator::PrintEnum(const EnumDescriptor& enum_descriptor) const { printer_->Print("containing_type=None,\n"); printer_->Print("options=$options_value$,\n", "options_value", - OptionsValue("EnumOptions", CEscape(options_string))); + OptionsValue("EnumOptions", options_string)); EnumDescriptorProto edp; PrintSerializedPbInterval(enum_descriptor, edp); printer_->Outdent(); @@ -674,6 +672,17 @@ void Generator::FixForeignFieldsInDescriptor( } } +void Generator::AddMessageToFileDescriptor(const Descriptor& descriptor) const { + map<string, string> m; + m["descriptor_name"] = kDescriptorKey; + m["message_name"] = descriptor.name(); + m["message_descriptor_name"] = ModuleLevelDescriptorName(descriptor); + const char file_descriptor_template[] = + "$descriptor_name$.message_types_by_name['$message_name$'] = " + "$message_descriptor_name$\n"; + printer_->Print(m, file_descriptor_template); +} + // Sets any necessary message_type and enum_type attributes // for the Python version of |field|. // @@ -752,6 +761,9 @@ void Generator::FixForeignFieldsInDescriptors() const { for (int i = 0; i < file_->message_type_count(); ++i) { FixForeignFieldsInDescriptor(*file_->message_type(i), NULL); } + for (int i = 0; i < file_->message_type_count(); ++i) { + AddMessageToFileDescriptor(*file_->message_type(i)); + } printer_->Print("\n"); } @@ -823,6 +835,8 @@ void Generator::PrintEnumValueDescriptor( " type=None)"); } +// Returns a Python expression that calls descriptor._ParseOptions using +// the given descriptor class name and serialized options protobuf string. string Generator::OptionsValue( const string& class_name, const string& serialized_options) const { if (serialized_options.length() == 0 || GeneratingDescriptorProto()) { diff --git a/third_party/protobuf/src/google/protobuf/compiler/python/python_generator.h b/third_party/protobuf/src/google/protobuf/compiler/python/python_generator.h index 43c2087..84eaf8a 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/python/python_generator.h +++ b/third_party/protobuf/src/google/protobuf/compiler/python/python_generator.h @@ -66,7 +66,7 @@ class LIBPROTOC_EXPORT Generator : public CodeGenerator { // CodeGenerator methods. virtual bool Generate(const FileDescriptor* file, const string& parameter, - OutputDirectory* output_directory, + GeneratorContext* generator_context, string* error) const; private: @@ -104,6 +104,7 @@ class LIBPROTOC_EXPORT Generator : public CodeGenerator { void FixForeignFieldsInField(const Descriptor* containing_type, const FieldDescriptor& field, const string& python_dict_name) const; + void AddMessageToFileDescriptor(const Descriptor& descriptor) const; string FieldReferencingExpression(const Descriptor* containing_type, const FieldDescriptor& field, const string& python_dict_name) const; diff --git a/third_party/protobuf/src/google/protobuf/compiler/python/python_plugin_unittest.cc b/third_party/protobuf/src/google/protobuf/compiler/python/python_plugin_unittest.cc index fde8876..da619ad 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/python/python_plugin_unittest.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/python/python_plugin_unittest.cc @@ -56,19 +56,19 @@ class TestGenerator : public CodeGenerator { virtual bool Generate(const FileDescriptor* file, const string& parameter, - OutputDirectory* output_directory, + GeneratorContext* context, string* error) const { - TryInsert("test_pb2.py", "imports", output_directory); - TryInsert("test_pb2.py", "module_scope", output_directory); - TryInsert("test_pb2.py", "class_scope:foo.Bar", output_directory); - TryInsert("test_pb2.py", "class_scope:foo.Bar.Baz", output_directory); + TryInsert("test_pb2.py", "imports", context); + TryInsert("test_pb2.py", "module_scope", context); + TryInsert("test_pb2.py", "class_scope:foo.Bar", context); + TryInsert("test_pb2.py", "class_scope:foo.Bar.Baz", context); return true; } void TryInsert(const string& filename, const string& insertion_point, - OutputDirectory* output_directory) const { + GeneratorContext* context) const { scoped_ptr<io::ZeroCopyOutputStream> output( - output_directory->OpenForInsert(filename, insertion_point)); + context->OpenForInsert(filename, insertion_point)); io::Printer printer(output.get(), '$'); printer.Print("// inserted $name$\n", "name", insertion_point); } diff --git a/third_party/protobuf/src/google/protobuf/compiler/subprocess.cc b/third_party/protobuf/src/google/protobuf/compiler/subprocess.cc index dbd813e..5fb5d5c 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/subprocess.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/subprocess.cc @@ -32,6 +32,8 @@ #include <google/protobuf/compiler/subprocess.h> +#include <algorithm> + #ifndef _WIN32 #include <errno.h> #include <sys/select.h> @@ -39,7 +41,6 @@ #include <signal.h> #endif -#include <algorithm> #include <google/protobuf/stubs/common.h> #include <google/protobuf/message.h> #include <google/protobuf/stubs/substitute.h> diff --git a/third_party/protobuf/src/google/protobuf/compiler/subprocess.h b/third_party/protobuf/src/google/protobuf/compiler/subprocess.h index 7a6fa70..de9fce9 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/subprocess.h +++ b/third_party/protobuf/src/google/protobuf/compiler/subprocess.h @@ -40,9 +40,10 @@ #include <sys/types.h> #include <unistd.h> #endif // !_WIN32 +#include <google/protobuf/stubs/common.h> #include <string> -#include <google/protobuf/stubs/common.h> + namespace google { namespace protobuf { diff --git a/third_party/protobuf/src/google/protobuf/compiler/zip_output_unittest.sh b/third_party/protobuf/src/google/protobuf/compiler/zip_output_unittest.sh index 259d5d2..3a02436 100755 --- a/third_party/protobuf/src/google/protobuf/compiler/zip_output_unittest.sh +++ b/third_party/protobuf/src/google/protobuf/compiler/zip_output_unittest.sh @@ -39,45 +39,51 @@ fail() { exit 1 } +TEST_TMPDIR=. +PROTOC=./protoc + echo ' + syntax = "proto2"; option java_multiple_files = true; option java_package = "test.jar"; option java_outer_classname = "Outer"; message Foo {} message Bar {} -' > testzip.proto +' > $TEST_TMPDIR/testzip.proto -./protoc --cpp_out=testzip.zip --python_out=testzip.zip --java_out=testzip.jar \ - testzip.proto || fail 'protoc failed.' +$PROTOC \ + --cpp_out=$TEST_TMPDIR/testzip.zip --python_out=$TEST_TMPDIR/testzip.zip \ + --java_out=$TEST_TMPDIR/testzip.jar -I$TEST_TMPDIR testzip.proto \ + || fail 'protoc failed.' echo "Testing output to zip..." if unzip -h > /dev/null; then - unzip -t testzip.zip > testzip.list || fail 'unzip failed.' + unzip -t $TEST_TMPDIR/testzip.zip > $TEST_TMPDIR/testzip.list || fail 'unzip failed.' - grep 'testing: testzip\.pb\.cc *OK$' testzip.list > /dev/null \ + grep 'testing: testzip\.pb\.cc *OK$' $TEST_TMPDIR/testzip.list > /dev/null \ || fail 'testzip.pb.cc not found in output zip.' - grep 'testing: testzip\.pb\.h *OK$' testzip.list > /dev/null \ + grep 'testing: testzip\.pb\.h *OK$' $TEST_TMPDIR/testzip.list > /dev/null \ || fail 'testzip.pb.h not found in output zip.' - grep 'testing: testzip_pb2\.py *OK$' testzip.list > /dev/null \ + grep 'testing: testzip_pb2\.py *OK$' $TEST_TMPDIR/testzip.list > /dev/null \ || fail 'testzip_pb2.py not found in output zip.' - grep -i 'manifest' testzip.list > /dev/null \ + grep -i 'manifest' $TEST_TMPDIR/testzip.list > /dev/null \ && fail 'Zip file contained manifest.' else echo "Warning: 'unzip' command not available. Skipping test." fi echo "Testing output to jar..." -if jar c testzip.proto > /dev/null; then - jar tf testzip.jar > testzip.list || fail 'jar failed.' +if jar c $TEST_TMPDIR/testzip.proto > /dev/null; then + jar tf $TEST_TMPDIR/testzip.jar > $TEST_TMPDIR/testzip.list || fail 'jar failed.' - grep '^test/jar/Foo\.java$' testzip.list > /dev/null \ + grep '^test/jar/Foo\.java$' $TEST_TMPDIR/testzip.list > /dev/null \ || fail 'Foo.java not found in output jar.' - grep '^test/jar/Bar\.java$' testzip.list > /dev/null \ + grep '^test/jar/Bar\.java$' $TEST_TMPDIR/testzip.list > /dev/null \ || fail 'Bar.java not found in output jar.' - grep '^test/jar/Outer\.java$' testzip.list > /dev/null \ + grep '^test/jar/Outer\.java$' $TEST_TMPDIR/testzip.list > /dev/null \ || fail 'Outer.java not found in output jar.' - grep '^META-INF/MANIFEST\.MF$' testzip.list > /dev/null \ - || fail 'Manifest not ofund in output jar.' + grep '^META-INF/MANIFEST\.MF$' $TEST_TMPDIR/testzip.list > /dev/null \ + || fail 'Manifest not found in output jar.' else echo "Warning: 'jar' command not available. Skipping test." fi diff --git a/third_party/protobuf/src/google/protobuf/compiler/zip_writer.cc b/third_party/protobuf/src/google/protobuf/compiler/zip_writer.cc index 53c1877..65d7352 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/zip_writer.cc +++ b/third_party/protobuf/src/google/protobuf/compiler/zip_writer.cc @@ -28,6 +28,36 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// 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: ambrose@google.com (Ambrose Feinstein), // kenton@google.com (Kenton Varda) // @@ -183,6 +213,6 @@ bool ZipWriter::WriteDirectory() { return output.HadError(); } -} // namespace google -} // namespace protobuf } // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/third_party/protobuf/src/google/protobuf/compiler/zip_writer.h b/third_party/protobuf/src/google/protobuf/compiler/zip_writer.h index 4289553..be73972 100644 --- a/third_party/protobuf/src/google/protobuf/compiler/zip_writer.h +++ b/third_party/protobuf/src/google/protobuf/compiler/zip_writer.h @@ -28,6 +28,36 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// 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) #include <vector> @@ -58,6 +88,6 @@ class ZipWriter { vector<FileInfo> files_; }; -} // namespace google -} // namespace protobuf } // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/third_party/protobuf/src/google/protobuf/descriptor.cc b/third_party/protobuf/src/google/protobuf/descriptor.cc index 6c9648b..b58a22b 100644 --- a/third_party/protobuf/src/google/protobuf/descriptor.cc +++ b/third_party/protobuf/src/google/protobuf/descriptor.cc @@ -42,10 +42,12 @@ #include <google/protobuf/descriptor.h> #include <google/protobuf/descriptor_database.h> #include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/dynamic_message.h> #include <google/protobuf/text_format.h> #include <google/protobuf/unknown_field_set.h> #include <google/protobuf/wire_format.h> #include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/io/tokenizer.h> #include <google/protobuf/io/zero_copy_stream_impl.h> #include <google/protobuf/stubs/common.h> #include <google/protobuf/stubs/once.h> @@ -2056,6 +2058,8 @@ class DescriptorBuilder { // Otherwise returns true. bool InterpretOptions(OptionsToInterpret* options_to_interpret); + class AggregateOptionFinder; + private: // Interprets uninterpreted_option_ on the specified message, which // must be the mutable copy of the original options message to which @@ -2082,6 +2086,11 @@ class DescriptorBuilder { bool SetOptionValue(const FieldDescriptor* option_field, UnknownFieldSet* unknown_fields); + // Parses an aggregate value for a CPPTYPE_MESSAGE option and + // saves it into *unknown_fields. + bool SetAggregateOption(const FieldDescriptor* option_field, + UnknownFieldSet* unknown_fields); + // Convenience functions to set an int field the right way, depending on // its wire type (a single int CppType can represent multiple wire types). void SetInt32(int number, int32 value, FieldDescriptor::Type type, @@ -2128,6 +2137,10 @@ class DescriptorBuilder { // can use it to find locations recorded by the parser. const UninterpretedOption* uninterpreted_option_; + // Factory used to create the dynamic messages we need to parse + // any aggregate option values we encounter. + DynamicMessageFactory dynamic_factory_; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(OptionInterpreter); }; @@ -2139,6 +2152,8 @@ class DescriptorBuilder { // redundantly declare OptionInterpreter a friend just to make things extra // clear for these bad compilers. friend class OptionInterpreter; + friend class OptionInterpreter::AggregateOptionFinder; + static inline bool get_allow_unknown(const DescriptorPool* pool) { return pool->allow_unknown_; } @@ -3973,9 +3988,6 @@ bool DescriptorBuilder::OptionInterpreter::InterpretSingleOption( intermediate_fields.push_back(field); descriptor = field->message_type(); } - } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - return AddNameError("Option field \"" + debug_msg_name + - "\" cannot be of message type."); } } @@ -4310,18 +4322,95 @@ bool DescriptorBuilder::OptionInterpreter::SetOptionValue( break; case FieldDescriptor::CPPTYPE_MESSAGE: - // We don't currently support defining a message-typed option, so we - // should never actually get here. - return AddValueError("Option \"" + option_field->full_name() + - "\" is a message. To set fields within it, use " - "syntax like \"" + option_field->name() + - ".foo = value\"."); + if (!SetAggregateOption(option_field, unknown_fields)) { + return false; + } break; } return true; } +class DescriptorBuilder::OptionInterpreter::AggregateOptionFinder + : public TextFormat::Finder { + public: + DescriptorBuilder* builder_; + + virtual const FieldDescriptor* FindExtension( + Message* message, const string& name) const { + if (builder_->pool_->mutex_ != NULL) { + builder_->pool_->mutex_->AssertHeld(); + } + Symbol result = builder_->LookupSymbolNoPlaceholder( + name, message->GetDescriptor()->full_name()); + if (result.type == Symbol::FIELD && + result.field_descriptor->is_extension()) { + return result.field_descriptor; + } else { + return NULL; + } + } +}; + +// A custom error collector to record any text-format parsing errors +namespace { +class AggregateErrorCollector : public io::ErrorCollector { + public: + string error_; + + virtual void AddError(int line, int column, const string& message) { + if (!error_.empty()) { + error_ += "; "; + } + error_ += message; + } + + virtual void AddWarning(int line, int column, const string& message) { + // Ignore warnings + } +}; +} + +// We construct a dynamic message of the type corresponding to +// option_field, parse the supplied text-format string into this +// message, and serialize the resulting message to produce the value. +bool DescriptorBuilder::OptionInterpreter::SetAggregateOption( + const FieldDescriptor* option_field, + UnknownFieldSet* unknown_fields) { + if (!uninterpreted_option_->has_aggregate_value()) { + return AddValueError("Option \"" + option_field->full_name() + + "\" is a message. To set the entire message, use " + "syntax like \"" + option_field->name() + + " = { <proto text format> }\". " + "To set fields within it, use " + "syntax like \"" + option_field->name() + + ".foo = value\"."); + } + + const Descriptor* type = option_field->message_type(); + scoped_ptr<Message> dynamic(dynamic_factory_.GetPrototype(type)->New()); + GOOGLE_CHECK(dynamic.get() != NULL) + << "Could not create an instance of " << option_field->DebugString(); + + AggregateErrorCollector collector; + AggregateOptionFinder finder; + finder.builder_ = builder_; + TextFormat::Parser parser; + parser.RecordErrorsTo(&collector); + parser.SetFinder(&finder); + if (!parser.ParseFromString(uninterpreted_option_->aggregate_value(), + dynamic.get())) { + AddValueError("Error while parsing option value for \"" + + option_field->name() + "\": " + collector.error_); + return false; + } else { + string serial; + dynamic->SerializeToString(&serial); // Never fails + unknown_fields->AddLengthDelimited(option_field->number(), serial); + return true; + } +} + void DescriptorBuilder::OptionInterpreter::SetInt32(int number, int32 value, FieldDescriptor::Type type, UnknownFieldSet* unknown_fields) { switch (type) { diff --git a/third_party/protobuf/src/google/protobuf/descriptor.pb.cc b/third_party/protobuf/src/google/protobuf/descriptor.pb.cc index c9f1079..468b433 100644 --- a/third_party/protobuf/src/google/protobuf/descriptor.pb.cc +++ b/third_party/protobuf/src/google/protobuf/descriptor.pb.cc @@ -76,6 +76,12 @@ const ::google::protobuf::internal::GeneratedMessageReflection* const ::google::protobuf::Descriptor* UninterpretedOption_NamePart_descriptor_ = NULL; const ::google::protobuf::internal::GeneratedMessageReflection* UninterpretedOption_NamePart_reflection_ = NULL; +const ::google::protobuf::Descriptor* SourceCodeInfo_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + SourceCodeInfo_reflection_ = NULL; +const ::google::protobuf::Descriptor* SourceCodeInfo_Location_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + SourceCodeInfo_Location_reflection_ = NULL; } // namespace @@ -102,7 +108,7 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() { ::google::protobuf::MessageFactory::generated_factory(), sizeof(FileDescriptorSet)); FileDescriptorProto_descriptor_ = file->message_type(1); - static const int FileDescriptorProto_offsets_[8] = { + static const int FileDescriptorProto_offsets_[9] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, name_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, package_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, dependency_), @@ -111,6 +117,7 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, service_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, extension_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, options_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, source_code_info_), }; FileDescriptorProto_reflection_ = new ::google::protobuf::internal::GeneratedMessageReflection( @@ -254,11 +261,12 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() { ::google::protobuf::MessageFactory::generated_factory(), sizeof(MethodDescriptorProto)); FileOptions_descriptor_ = file->message_type(8); - static const int FileOptions_offsets_[9] = { + static const int FileOptions_offsets_[10] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_package_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_outer_classname_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_multiple_files_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, retain_unknown_fields_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_generate_equals_and_hash_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, optimize_for_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, cc_generic_services_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_generic_services_), @@ -375,13 +383,14 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() { ::google::protobuf::MessageFactory::generated_factory(), sizeof(MethodOptions)); UninterpretedOption_descriptor_ = file->message_type(15); - static const int UninterpretedOption_offsets_[6] = { + static const int UninterpretedOption_offsets_[7] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, name_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, identifier_value_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, positive_int_value_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, negative_int_value_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, double_value_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, string_value_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, aggregate_value_), }; UninterpretedOption_reflection_ = new ::google::protobuf::internal::GeneratedMessageReflection( @@ -410,6 +419,37 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() { ::google::protobuf::DescriptorPool::generated_pool(), ::google::protobuf::MessageFactory::generated_factory(), sizeof(UninterpretedOption_NamePart)); + SourceCodeInfo_descriptor_ = file->message_type(16); + static const int SourceCodeInfo_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo, location_), + }; + SourceCodeInfo_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + SourceCodeInfo_descriptor_, + SourceCodeInfo::default_instance_, + SourceCodeInfo_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(SourceCodeInfo)); + SourceCodeInfo_Location_descriptor_ = SourceCodeInfo_descriptor_->nested_type(0); + static const int SourceCodeInfo_Location_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo_Location, path_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo_Location, span_), + }; + SourceCodeInfo_Location_reflection_ = + new ::google::protobuf::internal::GeneratedMessageReflection( + SourceCodeInfo_Location_descriptor_, + SourceCodeInfo_Location::default_instance_, + SourceCodeInfo_Location_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo_Location, _has_bits_[0]), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo_Location, _unknown_fields_), + -1, + ::google::protobuf::DescriptorPool::generated_pool(), + ::google::protobuf::MessageFactory::generated_factory(), + sizeof(SourceCodeInfo_Location)); } namespace { @@ -458,6 +498,10 @@ void protobuf_RegisterTypes(const ::std::string&) { UninterpretedOption_descriptor_, &UninterpretedOption::default_instance()); ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( UninterpretedOption_NamePart_descriptor_, &UninterpretedOption_NamePart::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + SourceCodeInfo_descriptor_, &SourceCodeInfo::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + SourceCodeInfo_Location_descriptor_, &SourceCodeInfo_Location::default_instance()); } } // namespace @@ -499,6 +543,10 @@ void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto() { delete UninterpretedOption_reflection_; delete UninterpretedOption_NamePart::default_instance_; delete UninterpretedOption_NamePart_reflection_; + delete SourceCodeInfo::default_instance_; + delete SourceCodeInfo_reflection_; + delete SourceCodeInfo_Location::default_instance_; + delete SourceCodeInfo_Location_reflection_; } void protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto() { @@ -511,7 +559,7 @@ void protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto() { "\n google/protobuf/descriptor.proto\022\017goog" "le.protobuf\"G\n\021FileDescriptorSet\0222\n\004file" "\030\001 \003(\0132$.google.protobuf.FileDescriptorP" - "roto\"\334\002\n\023FileDescriptorProto\022\014\n\004name\030\001 \001" + "roto\"\227\003\n\023FileDescriptorProto\022\014\n\004name\030\001 \001" "(\t\022\017\n\007package\030\002 \001(\t\022\022\n\ndependency\030\003 \003(\t\022" "6\n\014message_type\030\004 \003(\0132 .google.protobuf." "DescriptorProto\0227\n\tenum_type\030\005 \003(\0132$.goo" @@ -519,88 +567,95 @@ void protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto() { "ice\030\006 \003(\0132\'.google.protobuf.ServiceDescr" "iptorProto\0228\n\textension\030\007 \003(\0132%.google.p" "rotobuf.FieldDescriptorProto\022-\n\007options\030" - "\010 \001(\0132\034.google.protobuf.FileOptions\"\251\003\n\017" - "DescriptorProto\022\014\n\004name\030\001 \001(\t\0224\n\005field\030\002" - " \003(\0132%.google.protobuf.FieldDescriptorPr" - "oto\0228\n\textension\030\006 \003(\0132%.google.protobuf" - ".FieldDescriptorProto\0225\n\013nested_type\030\003 \003" - "(\0132 .google.protobuf.DescriptorProto\0227\n\t" - "enum_type\030\004 \003(\0132$.google.protobuf.EnumDe" - "scriptorProto\022H\n\017extension_range\030\005 \003(\0132/" - ".google.protobuf.DescriptorProto.Extensi" - "onRange\0220\n\007options\030\007 \001(\0132\037.google.protob" - "uf.MessageOptions\032,\n\016ExtensionRange\022\r\n\005s" - "tart\030\001 \001(\005\022\013\n\003end\030\002 \001(\005\"\224\005\n\024FieldDescrip" - "torProto\022\014\n\004name\030\001 \001(\t\022\016\n\006number\030\003 \001(\005\022:" - "\n\005label\030\004 \001(\0162+.google.protobuf.FieldDes" - "criptorProto.Label\0228\n\004type\030\005 \001(\0162*.googl" - "e.protobuf.FieldDescriptorProto.Type\022\021\n\t" - "type_name\030\006 \001(\t\022\020\n\010extendee\030\002 \001(\t\022\025\n\rdef" - "ault_value\030\007 \001(\t\022.\n\007options\030\010 \001(\0132\035.goog" - "le.protobuf.FieldOptions\"\266\002\n\004Type\022\017\n\013TYP" - "E_DOUBLE\020\001\022\016\n\nTYPE_FLOAT\020\002\022\016\n\nTYPE_INT64" - "\020\003\022\017\n\013TYPE_UINT64\020\004\022\016\n\nTYPE_INT32\020\005\022\020\n\014T" - "YPE_FIXED64\020\006\022\020\n\014TYPE_FIXED32\020\007\022\r\n\tTYPE_" - "BOOL\020\010\022\017\n\013TYPE_STRING\020\t\022\016\n\nTYPE_GROUP\020\n\022" - "\020\n\014TYPE_MESSAGE\020\013\022\016\n\nTYPE_BYTES\020\014\022\017\n\013TYP" - "E_UINT32\020\r\022\r\n\tTYPE_ENUM\020\016\022\021\n\rTYPE_SFIXED" - "32\020\017\022\021\n\rTYPE_SFIXED64\020\020\022\017\n\013TYPE_SINT32\020\021" - "\022\017\n\013TYPE_SINT64\020\022\"C\n\005Label\022\022\n\016LABEL_OPTI" - "ONAL\020\001\022\022\n\016LABEL_REQUIRED\020\002\022\022\n\016LABEL_REPE" - "ATED\020\003\"\214\001\n\023EnumDescriptorProto\022\014\n\004name\030\001" - " \001(\t\0228\n\005value\030\002 \003(\0132).google.protobuf.En" - "umValueDescriptorProto\022-\n\007options\030\003 \001(\0132" - "\034.google.protobuf.EnumOptions\"l\n\030EnumVal" - "ueDescriptorProto\022\014\n\004name\030\001 \001(\t\022\016\n\006numbe" - "r\030\002 \001(\005\0222\n\007options\030\003 \001(\0132!.google.protob" - "uf.EnumValueOptions\"\220\001\n\026ServiceDescripto" - "rProto\022\014\n\004name\030\001 \001(\t\0226\n\006method\030\002 \003(\0132&.g" - "oogle.protobuf.MethodDescriptorProto\0220\n\007" - "options\030\003 \001(\0132\037.google.protobuf.ServiceO" - "ptions\"\177\n\025MethodDescriptorProto\022\014\n\004name\030" - "\001 \001(\t\022\022\n\ninput_type\030\002 \001(\t\022\023\n\013output_type" - "\030\003 \001(\t\022/\n\007options\030\004 \001(\0132\036.google.protobu" - "f.MethodOptions\"\312\003\n\013FileOptions\022\024\n\014java_" - "package\030\001 \001(\t\022\034\n\024java_outer_classname\030\010 " - "\001(\t\022\"\n\023java_multiple_files\030\n \001(\010:\005false\022" - "$\n\025retain_unknown_fields\030\013 \001(\010:\005false\022F\n" - "\014optimize_for\030\t \001(\0162).google.protobuf.Fi" - "leOptions.OptimizeMode:\005SPEED\022!\n\023cc_gene" - "ric_services\030\020 \001(\010:\004true\022#\n\025java_generic" - "_services\030\021 \001(\010:\004true\022!\n\023py_generic_serv" - "ices\030\022 \001(\010:\004true\022C\n\024uninterpreted_option" - "\030\347\007 \003(\0132$.google.protobuf.UninterpretedO" - "ption\":\n\014OptimizeMode\022\t\n\005SPEED\020\001\022\r\n\tCODE" - "_SIZE\020\002\022\020\n\014LITE_RUNTIME\020\003*\t\010\350\007\020\200\200\200\200\002\"\270\001\n" - "\016MessageOptions\022&\n\027message_set_wire_form" - "at\030\001 \001(\010:\005false\022.\n\037no_standard_descripto" - "r_accessor\030\002 \001(\010:\005false\022C\n\024uninterpreted" + "\010 \001(\0132\034.google.protobuf.FileOptions\0229\n\020s" + "ource_code_info\030\t \001(\0132\037.google.protobuf." + "SourceCodeInfo\"\251\003\n\017DescriptorProto\022\014\n\004na" + "me\030\001 \001(\t\0224\n\005field\030\002 \003(\0132%.google.protobu" + "f.FieldDescriptorProto\0228\n\textension\030\006 \003(" + "\0132%.google.protobuf.FieldDescriptorProto" + "\0225\n\013nested_type\030\003 \003(\0132 .google.protobuf." + "DescriptorProto\0227\n\tenum_type\030\004 \003(\0132$.goo" + "gle.protobuf.EnumDescriptorProto\022H\n\017exte" + "nsion_range\030\005 \003(\0132/.google.protobuf.Desc" + "riptorProto.ExtensionRange\0220\n\007options\030\007 " + "\001(\0132\037.google.protobuf.MessageOptions\032,\n\016" + "ExtensionRange\022\r\n\005start\030\001 \001(\005\022\013\n\003end\030\002 \001" + "(\005\"\224\005\n\024FieldDescriptorProto\022\014\n\004name\030\001 \001(" + "\t\022\016\n\006number\030\003 \001(\005\022:\n\005label\030\004 \001(\0162+.googl" + "e.protobuf.FieldDescriptorProto.Label\0228\n" + "\004type\030\005 \001(\0162*.google.protobuf.FieldDescr" + "iptorProto.Type\022\021\n\ttype_name\030\006 \001(\t\022\020\n\010ex" + "tendee\030\002 \001(\t\022\025\n\rdefault_value\030\007 \001(\t\022.\n\007o" + "ptions\030\010 \001(\0132\035.google.protobuf.FieldOpti" + "ons\"\266\002\n\004Type\022\017\n\013TYPE_DOUBLE\020\001\022\016\n\nTYPE_FL" + "OAT\020\002\022\016\n\nTYPE_INT64\020\003\022\017\n\013TYPE_UINT64\020\004\022\016" + "\n\nTYPE_INT32\020\005\022\020\n\014TYPE_FIXED64\020\006\022\020\n\014TYPE" + "_FIXED32\020\007\022\r\n\tTYPE_BOOL\020\010\022\017\n\013TYPE_STRING" + "\020\t\022\016\n\nTYPE_GROUP\020\n\022\020\n\014TYPE_MESSAGE\020\013\022\016\n\n" + "TYPE_BYTES\020\014\022\017\n\013TYPE_UINT32\020\r\022\r\n\tTYPE_EN" + "UM\020\016\022\021\n\rTYPE_SFIXED32\020\017\022\021\n\rTYPE_SFIXED64" + "\020\020\022\017\n\013TYPE_SINT32\020\021\022\017\n\013TYPE_SINT64\020\022\"C\n\005" + "Label\022\022\n\016LABEL_OPTIONAL\020\001\022\022\n\016LABEL_REQUI" + "RED\020\002\022\022\n\016LABEL_REPEATED\020\003\"\214\001\n\023EnumDescri" + "ptorProto\022\014\n\004name\030\001 \001(\t\0228\n\005value\030\002 \003(\0132)" + ".google.protobuf.EnumValueDescriptorProt" + "o\022-\n\007options\030\003 \001(\0132\034.google.protobuf.Enu" + "mOptions\"l\n\030EnumValueDescriptorProto\022\014\n\004" + "name\030\001 \001(\t\022\016\n\006number\030\002 \001(\005\0222\n\007options\030\003 " + "\001(\0132!.google.protobuf.EnumValueOptions\"\220" + "\001\n\026ServiceDescriptorProto\022\014\n\004name\030\001 \001(\t\022" + "6\n\006method\030\002 \003(\0132&.google.protobuf.Method" + "DescriptorProto\0220\n\007options\030\003 \001(\0132\037.googl" + "e.protobuf.ServiceOptions\"\177\n\025MethodDescr" + "iptorProto\022\014\n\004name\030\001 \001(\t\022\022\n\ninput_type\030\002" + " \001(\t\022\023\n\013output_type\030\003 \001(\t\022/\n\007options\030\004 \001" + "(\0132\036.google.protobuf.MethodOptions\"\373\003\n\013F" + "ileOptions\022\024\n\014java_package\030\001 \001(\t\022\034\n\024java" + "_outer_classname\030\010 \001(\t\022\"\n\023java_multiple_" + "files\030\n \001(\010:\005false\022$\n\025retain_unknown_fie" + "lds\030\013 \001(\010:\005false\022,\n\035java_generate_equals" + "_and_hash\030\024 \001(\010:\005false\022F\n\014optimize_for\030\t" + " \001(\0162).google.protobuf.FileOptions.Optim" + "izeMode:\005SPEED\022\"\n\023cc_generic_services\030\020 " + "\001(\010:\005false\022$\n\025java_generic_services\030\021 \001(" + "\010:\005false\022\"\n\023py_generic_services\030\022 \001(\010:\005f" + "alse\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.go" + "ogle.protobuf.UninterpretedOption\":\n\014Opt" + "imizeMode\022\t\n\005SPEED\020\001\022\r\n\tCODE_SIZE\020\002\022\020\n\014L" + "ITE_RUNTIME\020\003*\t\010\350\007\020\200\200\200\200\002\"\270\001\n\016MessageOpti" + "ons\022&\n\027message_set_wire_format\030\001 \001(\010:\005fa" + "lse\022.\n\037no_standard_descriptor_accessor\030\002" + " \001(\010:\005false\022C\n\024uninterpreted_option\030\347\007 \003" + "(\0132$.google.protobuf.UninterpretedOption" + "*\t\010\350\007\020\200\200\200\200\002\"\224\002\n\014FieldOptions\022:\n\005ctype\030\001 " + "\001(\0162#.google.protobuf.FieldOptions.CType" + ":\006STRING\022\016\n\006packed\030\002 \001(\010\022\031\n\ndeprecated\030\003" + " \001(\010:\005false\022\034\n\024experimental_map_key\030\t \001(" + "\t\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.googl" + "e.protobuf.UninterpretedOption\"/\n\005CType\022" + "\n\n\006STRING\020\000\022\010\n\004CORD\020\001\022\020\n\014STRING_PIECE\020\002*" + "\t\010\350\007\020\200\200\200\200\002\"]\n\013EnumOptions\022C\n\024uninterpret" + "ed_option\030\347\007 \003(\0132$.google.protobuf.Unint" + "erpretedOption*\t\010\350\007\020\200\200\200\200\002\"b\n\020EnumValueOp" + "tions\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.g" + "oogle.protobuf.UninterpretedOption*\t\010\350\007\020" + "\200\200\200\200\002\"`\n\016ServiceOptions\022C\n\024uninterpreted" "_option\030\347\007 \003(\0132$.google.protobuf.Uninter" - "pretedOption*\t\010\350\007\020\200\200\200\200\002\"\224\002\n\014FieldOptions" - "\022:\n\005ctype\030\001 \001(\0162#.google.protobuf.FieldO" - "ptions.CType:\006STRING\022\016\n\006packed\030\002 \001(\010\022\031\n\n" - "deprecated\030\003 \001(\010:\005false\022\034\n\024experimental_" - "map_key\030\t \001(\t\022C\n\024uninterpreted_option\030\347\007" - " \003(\0132$.google.protobuf.UninterpretedOpti" - "on\"/\n\005CType\022\n\n\006STRING\020\000\022\010\n\004CORD\020\001\022\020\n\014STR" - "ING_PIECE\020\002*\t\010\350\007\020\200\200\200\200\002\"]\n\013EnumOptions\022C\n" - "\024uninterpreted_option\030\347\007 \003(\0132$.google.pr" - "otobuf.UninterpretedOption*\t\010\350\007\020\200\200\200\200\002\"b\n" - "\020EnumValueOptions\022C\n\024uninterpreted_optio" - "n\030\347\007 \003(\0132$.google.protobuf.Uninterpreted" - "Option*\t\010\350\007\020\200\200\200\200\002\"`\n\016ServiceOptions\022C\n\024u" - "ninterpreted_option\030\347\007 \003(\0132$.google.prot" - "obuf.UninterpretedOption*\t\010\350\007\020\200\200\200\200\002\"_\n\rM" - "ethodOptions\022C\n\024uninterpreted_option\030\347\007 " - "\003(\0132$.google.protobuf.UninterpretedOptio" - "n*\t\010\350\007\020\200\200\200\200\002\"\205\002\n\023UninterpretedOption\022;\n\004" - "name\030\002 \003(\0132-.google.protobuf.Uninterpret" - "edOption.NamePart\022\030\n\020identifier_value\030\003 " - "\001(\t\022\032\n\022positive_int_value\030\004 \001(\004\022\032\n\022negat" - "ive_int_value\030\005 \001(\003\022\024\n\014double_value\030\006 \001(" - "\001\022\024\n\014string_value\030\007 \001(\014\0323\n\010NamePart\022\021\n\tn" - "ame_part\030\001 \002(\t\022\024\n\014is_extension\030\002 \002(\010B)\n\023" - "com.google.protobufB\020DescriptorProtosH\001", 3719); + "pretedOption*\t\010\350\007\020\200\200\200\200\002\"_\n\rMethodOptions" + "\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.google" + ".protobuf.UninterpretedOption*\t\010\350\007\020\200\200\200\200\002" + "\"\236\002\n\023UninterpretedOption\022;\n\004name\030\002 \003(\0132-" + ".google.protobuf.UninterpretedOption.Nam" + "ePart\022\030\n\020identifier_value\030\003 \001(\t\022\032\n\022posit" + "ive_int_value\030\004 \001(\004\022\032\n\022negative_int_valu" + "e\030\005 \001(\003\022\024\n\014double_value\030\006 \001(\001\022\024\n\014string_" + "value\030\007 \001(\014\022\027\n\017aggregate_value\030\010 \001(\t\0323\n\010" + "NamePart\022\021\n\tname_part\030\001 \002(\t\022\024\n\014is_extens" + "ion\030\002 \002(\010\"|\n\016SourceCodeInfo\022:\n\010location\030" + "\001 \003(\0132(.google.protobuf.SourceCodeInfo.L" + "ocation\032.\n\010Location\022\020\n\004path\030\001 \003(\005B\002\020\001\022\020\n" + "\004span\030\002 \003(\005B\002\020\001B)\n\023com.google.protobufB\020" + "DescriptorProtosH\001", 3978); ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( "google/protobuf/descriptor.proto", &protobuf_RegisterTypes); FileDescriptorSet::default_instance_ = new FileDescriptorSet(); @@ -621,6 +676,8 @@ void protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto() { MethodOptions::default_instance_ = new MethodOptions(); UninterpretedOption::default_instance_ = new UninterpretedOption(); UninterpretedOption_NamePart::default_instance_ = new UninterpretedOption_NamePart(); + SourceCodeInfo::default_instance_ = new SourceCodeInfo(); + SourceCodeInfo_Location::default_instance_ = new SourceCodeInfo_Location(); FileDescriptorSet::default_instance_->InitAsDefaultInstance(); FileDescriptorProto::default_instance_->InitAsDefaultInstance(); DescriptorProto::default_instance_->InitAsDefaultInstance(); @@ -639,6 +696,8 @@ void protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto() { MethodOptions::default_instance_->InitAsDefaultInstance(); UninterpretedOption::default_instance_->InitAsDefaultInstance(); UninterpretedOption_NamePart::default_instance_->InitAsDefaultInstance(); + SourceCodeInfo::default_instance_->InitAsDefaultInstance(); + SourceCodeInfo_Location::default_instance_->InitAsDefaultInstance(); ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto); } @@ -856,8 +915,6 @@ void FileDescriptorSet::Swap(FileDescriptorSet* other) { // =================================================================== -const ::std::string FileDescriptorProto::_default_name_; -const ::std::string FileDescriptorProto::_default_package_; #ifndef _MSC_VER const int FileDescriptorProto::kNameFieldNumber; const int FileDescriptorProto::kPackageFieldNumber; @@ -867,6 +924,7 @@ const int FileDescriptorProto::kEnumTypeFieldNumber; const int FileDescriptorProto::kServiceFieldNumber; const int FileDescriptorProto::kExtensionFieldNumber; const int FileDescriptorProto::kOptionsFieldNumber; +const int FileDescriptorProto::kSourceCodeInfoFieldNumber; #endif // !_MSC_VER FileDescriptorProto::FileDescriptorProto() @@ -876,6 +934,7 @@ FileDescriptorProto::FileDescriptorProto() void FileDescriptorProto::InitAsDefaultInstance() { options_ = const_cast< ::google::protobuf::FileOptions*>(&::google::protobuf::FileOptions::default_instance()); + source_code_info_ = const_cast< ::google::protobuf::SourceCodeInfo*>(&::google::protobuf::SourceCodeInfo::default_instance()); } FileDescriptorProto::FileDescriptorProto(const FileDescriptorProto& from) @@ -886,9 +945,10 @@ FileDescriptorProto::FileDescriptorProto(const FileDescriptorProto& from) void FileDescriptorProto::SharedCtor() { _cached_size_ = 0; - name_ = const_cast< ::std::string*>(&_default_name_); - package_ = const_cast< ::std::string*>(&_default_package_); + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + package_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); options_ = NULL; + source_code_info_ = NULL; ::memset(_has_bits_, 0, sizeof(_has_bits_)); } @@ -897,14 +957,15 @@ FileDescriptorProto::~FileDescriptorProto() { } void FileDescriptorProto::SharedDtor() { - if (name_ != &_default_name_) { + if (name_ != &::google::protobuf::internal::kEmptyString) { delete name_; } - if (package_ != &_default_package_) { + if (package_ != &::google::protobuf::internal::kEmptyString) { delete package_; } if (this != default_instance_) { delete options_; + delete source_code_info_; } } @@ -930,20 +991,25 @@ FileDescriptorProto* FileDescriptorProto::New() const { void FileDescriptorProto::Clear() { if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (_has_bit(0)) { - if (name_ != &_default_name_) { + if (has_name()) { + if (name_ != &::google::protobuf::internal::kEmptyString) { name_->clear(); } } - if (_has_bit(1)) { - if (package_ != &_default_package_) { + if (has_package()) { + if (package_ != &::google::protobuf::internal::kEmptyString) { package_->clear(); } } - if (_has_bit(7)) { + if (has_options()) { if (options_ != NULL) options_->::google::protobuf::FileOptions::Clear(); } } + if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) { + if (has_source_code_info()) { + if (source_code_info_ != NULL) source_code_info_->::google::protobuf::SourceCodeInfo::Clear(); + } + } dependency_.Clear(); message_type_.Clear(); enum_type_.Clear(); @@ -1080,6 +1146,20 @@ bool FileDescriptorProto::MergePartialFromCodedStream( } else { goto handle_uninterpreted; } + if (input->ExpectTag(74)) goto parse_source_code_info; + break; + } + + // optional .google.protobuf.SourceCodeInfo source_code_info = 9; + case 9: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_source_code_info: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_source_code_info())); + } else { + goto handle_uninterpreted; + } if (input->ExpectAtEnd()) return true; break; } @@ -1102,7 +1182,7 @@ bool FileDescriptorProto::MergePartialFromCodedStream( void FileDescriptorProto::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // optional string name = 1; - if (_has_bit(0)) { + if (has_name()) { ::google::protobuf::internal::WireFormat::VerifyUTF8String( this->name().data(), this->name().length(), ::google::protobuf::internal::WireFormat::SERIALIZE); @@ -1111,7 +1191,7 @@ void FileDescriptorProto::SerializeWithCachedSizes( } // optional string package = 2; - if (_has_bit(1)) { + if (has_package()) { ::google::protobuf::internal::WireFormat::VerifyUTF8String( this->package().data(), this->package().length(), ::google::protobuf::internal::WireFormat::SERIALIZE); @@ -1153,11 +1233,17 @@ void FileDescriptorProto::SerializeWithCachedSizes( } // optional .google.protobuf.FileOptions options = 8; - if (_has_bit(7)) { + if (has_options()) { ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( 8, this->options(), output); } + // optional .google.protobuf.SourceCodeInfo source_code_info = 9; + if (has_source_code_info()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 9, this->source_code_info(), output); + } + if (!unknown_fields().empty()) { ::google::protobuf::internal::WireFormatLite::SerializeUnknownFields( unknown_fields(), output); @@ -1167,7 +1253,7 @@ void FileDescriptorProto::SerializeWithCachedSizes( ::google::protobuf::uint8* FileDescriptorProto::SerializeWithCachedSizesToArray( ::google::protobuf::uint8* target) const { // optional string name = 1; - if (_has_bit(0)) { + if (has_name()) { ::google::protobuf::internal::WireFormat::VerifyUTF8String( this->name().data(), this->name().length(), ::google::protobuf::internal::WireFormat::SERIALIZE); @@ -1177,7 +1263,7 @@ void FileDescriptorProto::SerializeWithCachedSizes( } // optional string package = 2; - if (_has_bit(1)) { + if (has_package()) { ::google::protobuf::internal::WireFormat::VerifyUTF8String( this->package().data(), this->package().length(), ::google::protobuf::internal::WireFormat::SERIALIZE); @@ -1224,12 +1310,19 @@ void FileDescriptorProto::SerializeWithCachedSizes( } // optional .google.protobuf.FileOptions options = 8; - if (_has_bit(7)) { + if (has_options()) { target = ::google::protobuf::internal::WireFormatLite:: WriteMessageNoVirtualToArray( 8, this->options(), target); } + // optional .google.protobuf.SourceCodeInfo source_code_info = 9; + if (has_source_code_info()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 9, this->source_code_info(), target); + } + if (!unknown_fields().empty()) { target = ::google::protobuf::internal::WireFormatLite::SerializeUnknownFieldsToArray( unknown_fields(), target); @@ -1263,6 +1356,15 @@ int FileDescriptorProto::ByteSize() const { } } + if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) { + // optional .google.protobuf.SourceCodeInfo source_code_info = 9; + if (has_source_code_info()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->source_code_info()); + } + + } // repeated string dependency = 3; total_size += 1 * this->dependency_size(); for (int i = 0; i < this->dependency_size(); i++) { @@ -1333,16 +1435,21 @@ void FileDescriptorProto::MergeFrom(const FileDescriptorProto& from) { service_.MergeFrom(from.service_); extension_.MergeFrom(from.extension_); if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (from._has_bit(0)) { + if (from.has_name()) { set_name(from.name()); } - if (from._has_bit(1)) { + if (from.has_package()) { set_package(from.package()); } - if (from._has_bit(7)) { + if (from.has_options()) { mutable_options()->::google::protobuf::FileOptions::MergeFrom(from.options()); } } + if (from._has_bits_[8 / 32] & (0xffu << (8 % 32))) { + if (from.has_source_code_info()) { + mutable_source_code_info()->::google::protobuf::SourceCodeInfo::MergeFrom(from.source_code_info()); + } + } mutable_unknown_fields()->MergeFrom(from.unknown_fields()); } @@ -1388,6 +1495,7 @@ void FileDescriptorProto::Swap(FileDescriptorProto* other) { service_.Swap(&other->service_); extension_.Swap(&other->extension_); std::swap(options_, other->options_); + std::swap(source_code_info_, other->source_code_info_); std::swap(_has_bits_[0], other->_has_bits_[0]); _unknown_fields_.Swap(&other->_unknown_fields_); std::swap(_cached_size_, other->_cached_size_); @@ -1482,7 +1590,7 @@ bool DescriptorProto_ExtensionRange::MergePartialFromCodedStream( DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( input, &start_))); - _set_bit(0); + set_has_start(); } else { goto handle_uninterpreted; } @@ -1498,7 +1606,7 @@ bool DescriptorProto_ExtensionRange::MergePartialFromCodedStream( DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( input, &end_))); - _set_bit(1); + set_has_end(); } else { goto handle_uninterpreted; } @@ -1524,12 +1632,12 @@ bool DescriptorProto_ExtensionRange::MergePartialFromCodedStream( void DescriptorProto_ExtensionRange::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // optional int32 start = 1; - if (_has_bit(0)) { + if (has_start()) { ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->start(), output); } // optional int32 end = 2; - if (_has_bit(1)) { + if (has_end()) { ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->end(), output); } @@ -1542,12 +1650,12 @@ void DescriptorProto_ExtensionRange::SerializeWithCachedSizes( ::google::protobuf::uint8* DescriptorProto_ExtensionRange::SerializeWithCachedSizesToArray( ::google::protobuf::uint8* target) const { // optional int32 start = 1; - if (_has_bit(0)) { + if (has_start()) { target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->start(), target); } // optional int32 end = 2; - if (_has_bit(1)) { + if (has_end()) { target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->end(), target); } @@ -1603,10 +1711,10 @@ void DescriptorProto_ExtensionRange::MergeFrom(const ::google::protobuf::Message void DescriptorProto_ExtensionRange::MergeFrom(const DescriptorProto_ExtensionRange& from) { GOOGLE_CHECK_NE(&from, this); if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (from._has_bit(0)) { + if (from.has_start()) { set_start(from.start()); } - if (from._has_bit(1)) { + if (from.has_end()) { set_end(from.end()); } } @@ -1651,7 +1759,6 @@ void DescriptorProto_ExtensionRange::Swap(DescriptorProto_ExtensionRange* other) // ------------------------------------------------------------------- -const ::std::string DescriptorProto::_default_name_; #ifndef _MSC_VER const int DescriptorProto::kNameFieldNumber; const int DescriptorProto::kFieldFieldNumber; @@ -1679,7 +1786,7 @@ DescriptorProto::DescriptorProto(const DescriptorProto& from) void DescriptorProto::SharedCtor() { _cached_size_ = 0; - name_ = const_cast< ::std::string*>(&_default_name_); + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); options_ = NULL; ::memset(_has_bits_, 0, sizeof(_has_bits_)); } @@ -1689,7 +1796,7 @@ DescriptorProto::~DescriptorProto() { } void DescriptorProto::SharedDtor() { - if (name_ != &_default_name_) { + if (name_ != &::google::protobuf::internal::kEmptyString) { delete name_; } if (this != default_instance_) { @@ -1719,12 +1826,12 @@ DescriptorProto* DescriptorProto::New() const { void DescriptorProto::Clear() { if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (_has_bit(0)) { - if (name_ != &_default_name_) { + if (has_name()) { + if (name_ != &::google::protobuf::internal::kEmptyString) { name_->clear(); } } - if (_has_bit(6)) { + if (has_options()) { if (options_ != NULL) options_->::google::protobuf::MessageOptions::Clear(); } } @@ -1866,7 +1973,7 @@ bool DescriptorProto::MergePartialFromCodedStream( void DescriptorProto::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // optional string name = 1; - if (_has_bit(0)) { + if (has_name()) { ::google::protobuf::internal::WireFormat::VerifyUTF8String( this->name().data(), this->name().length(), ::google::protobuf::internal::WireFormat::SERIALIZE); @@ -1905,7 +2012,7 @@ void DescriptorProto::SerializeWithCachedSizes( } // optional .google.protobuf.MessageOptions options = 7; - if (_has_bit(6)) { + if (has_options()) { ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( 7, this->options(), output); } @@ -1919,7 +2026,7 @@ void DescriptorProto::SerializeWithCachedSizes( ::google::protobuf::uint8* DescriptorProto::SerializeWithCachedSizesToArray( ::google::protobuf::uint8* target) const { // optional string name = 1; - if (_has_bit(0)) { + if (has_name()) { ::google::protobuf::internal::WireFormat::VerifyUTF8String( this->name().data(), this->name().length(), ::google::protobuf::internal::WireFormat::SERIALIZE); @@ -1964,7 +2071,7 @@ void DescriptorProto::SerializeWithCachedSizes( } // optional .google.protobuf.MessageOptions options = 7; - if (_has_bit(6)) { + if (has_options()) { target = ::google::protobuf::internal::WireFormatLite:: WriteMessageNoVirtualToArray( 7, this->options(), target); @@ -2067,10 +2174,10 @@ void DescriptorProto::MergeFrom(const DescriptorProto& from) { enum_type_.MergeFrom(from.enum_type_); extension_range_.MergeFrom(from.extension_range_); if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (from._has_bit(0)) { + if (from.has_name()) { set_name(from.name()); } - if (from._has_bit(6)) { + if (from.has_options()) { mutable_options()->::google::protobuf::MessageOptions::MergeFrom(from.options()); } } @@ -2211,10 +2318,6 @@ const FieldDescriptorProto_Label FieldDescriptorProto::Label_MIN; const FieldDescriptorProto_Label FieldDescriptorProto::Label_MAX; const int FieldDescriptorProto::Label_ARRAYSIZE; #endif // _MSC_VER -const ::std::string FieldDescriptorProto::_default_name_; -const ::std::string FieldDescriptorProto::_default_type_name_; -const ::std::string FieldDescriptorProto::_default_extendee_; -const ::std::string FieldDescriptorProto::_default_default_value_; #ifndef _MSC_VER const int FieldDescriptorProto::kNameFieldNumber; const int FieldDescriptorProto::kNumberFieldNumber; @@ -2243,13 +2346,13 @@ FieldDescriptorProto::FieldDescriptorProto(const FieldDescriptorProto& from) void FieldDescriptorProto::SharedCtor() { _cached_size_ = 0; - name_ = const_cast< ::std::string*>(&_default_name_); + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); number_ = 0; label_ = 1; type_ = 1; - type_name_ = const_cast< ::std::string*>(&_default_type_name_); - extendee_ = const_cast< ::std::string*>(&_default_extendee_); - default_value_ = const_cast< ::std::string*>(&_default_default_value_); + type_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + extendee_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + default_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); options_ = NULL; ::memset(_has_bits_, 0, sizeof(_has_bits_)); } @@ -2259,16 +2362,16 @@ FieldDescriptorProto::~FieldDescriptorProto() { } void FieldDescriptorProto::SharedDtor() { - if (name_ != &_default_name_) { + if (name_ != &::google::protobuf::internal::kEmptyString) { delete name_; } - if (type_name_ != &_default_type_name_) { + if (type_name_ != &::google::protobuf::internal::kEmptyString) { delete type_name_; } - if (extendee_ != &_default_extendee_) { + if (extendee_ != &::google::protobuf::internal::kEmptyString) { delete extendee_; } - if (default_value_ != &_default_default_value_) { + if (default_value_ != &::google::protobuf::internal::kEmptyString) { delete default_value_; } if (this != default_instance_) { @@ -2298,30 +2401,30 @@ FieldDescriptorProto* FieldDescriptorProto::New() const { void FieldDescriptorProto::Clear() { if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (_has_bit(0)) { - if (name_ != &_default_name_) { + if (has_name()) { + if (name_ != &::google::protobuf::internal::kEmptyString) { name_->clear(); } } number_ = 0; label_ = 1; type_ = 1; - if (_has_bit(4)) { - if (type_name_ != &_default_type_name_) { + if (has_type_name()) { + if (type_name_ != &::google::protobuf::internal::kEmptyString) { type_name_->clear(); } } - if (_has_bit(5)) { - if (extendee_ != &_default_extendee_) { + if (has_extendee()) { + if (extendee_ != &::google::protobuf::internal::kEmptyString) { extendee_->clear(); } } - if (_has_bit(6)) { - if (default_value_ != &_default_default_value_) { + if (has_default_value()) { + if (default_value_ != &::google::protobuf::internal::kEmptyString) { default_value_->clear(); } } - if (_has_bit(7)) { + if (has_options()) { if (options_ != NULL) options_->::google::protobuf::FieldOptions::Clear(); } } @@ -2376,7 +2479,7 @@ bool FieldDescriptorProto::MergePartialFromCodedStream( DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( input, &number_))); - _set_bit(1); + set_has_number(); } else { goto handle_uninterpreted; } @@ -2492,7 +2595,7 @@ bool FieldDescriptorProto::MergePartialFromCodedStream( void FieldDescriptorProto::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // optional string name = 1; - if (_has_bit(0)) { + if (has_name()) { ::google::protobuf::internal::WireFormat::VerifyUTF8String( this->name().data(), this->name().length(), ::google::protobuf::internal::WireFormat::SERIALIZE); @@ -2501,7 +2604,7 @@ void FieldDescriptorProto::SerializeWithCachedSizes( } // optional string extendee = 2; - if (_has_bit(5)) { + if (has_extendee()) { ::google::protobuf::internal::WireFormat::VerifyUTF8String( this->extendee().data(), this->extendee().length(), ::google::protobuf::internal::WireFormat::SERIALIZE); @@ -2510,24 +2613,24 @@ void FieldDescriptorProto::SerializeWithCachedSizes( } // optional int32 number = 3; - if (_has_bit(1)) { + if (has_number()) { ::google::protobuf::internal::WireFormatLite::WriteInt32(3, this->number(), output); } // optional .google.protobuf.FieldDescriptorProto.Label label = 4; - if (_has_bit(2)) { + if (has_label()) { ::google::protobuf::internal::WireFormatLite::WriteEnum( 4, this->label(), output); } // optional .google.protobuf.FieldDescriptorProto.Type type = 5; - if (_has_bit(3)) { + if (has_type()) { ::google::protobuf::internal::WireFormatLite::WriteEnum( 5, this->type(), output); } // optional string type_name = 6; - if (_has_bit(4)) { + if (has_type_name()) { ::google::protobuf::internal::WireFormat::VerifyUTF8String( this->type_name().data(), this->type_name().length(), ::google::protobuf::internal::WireFormat::SERIALIZE); @@ -2536,7 +2639,7 @@ void FieldDescriptorProto::SerializeWithCachedSizes( } // optional string default_value = 7; - if (_has_bit(6)) { + if (has_default_value()) { ::google::protobuf::internal::WireFormat::VerifyUTF8String( this->default_value().data(), this->default_value().length(), ::google::protobuf::internal::WireFormat::SERIALIZE); @@ -2545,7 +2648,7 @@ void FieldDescriptorProto::SerializeWithCachedSizes( } // optional .google.protobuf.FieldOptions options = 8; - if (_has_bit(7)) { + if (has_options()) { ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( 8, this->options(), output); } @@ -2559,7 +2662,7 @@ void FieldDescriptorProto::SerializeWithCachedSizes( ::google::protobuf::uint8* FieldDescriptorProto::SerializeWithCachedSizesToArray( ::google::protobuf::uint8* target) const { // optional string name = 1; - if (_has_bit(0)) { + if (has_name()) { ::google::protobuf::internal::WireFormat::VerifyUTF8String( this->name().data(), this->name().length(), ::google::protobuf::internal::WireFormat::SERIALIZE); @@ -2569,7 +2672,7 @@ void FieldDescriptorProto::SerializeWithCachedSizes( } // optional string extendee = 2; - if (_has_bit(5)) { + if (has_extendee()) { ::google::protobuf::internal::WireFormat::VerifyUTF8String( this->extendee().data(), this->extendee().length(), ::google::protobuf::internal::WireFormat::SERIALIZE); @@ -2579,24 +2682,24 @@ void FieldDescriptorProto::SerializeWithCachedSizes( } // optional int32 number = 3; - if (_has_bit(1)) { + if (has_number()) { target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(3, this->number(), target); } // optional .google.protobuf.FieldDescriptorProto.Label label = 4; - if (_has_bit(2)) { + if (has_label()) { target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( 4, this->label(), target); } // optional .google.protobuf.FieldDescriptorProto.Type type = 5; - if (_has_bit(3)) { + if (has_type()) { target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( 5, this->type(), target); } // optional string type_name = 6; - if (_has_bit(4)) { + if (has_type_name()) { ::google::protobuf::internal::WireFormat::VerifyUTF8String( this->type_name().data(), this->type_name().length(), ::google::protobuf::internal::WireFormat::SERIALIZE); @@ -2606,7 +2709,7 @@ void FieldDescriptorProto::SerializeWithCachedSizes( } // optional string default_value = 7; - if (_has_bit(6)) { + if (has_default_value()) { ::google::protobuf::internal::WireFormat::VerifyUTF8String( this->default_value().data(), this->default_value().length(), ::google::protobuf::internal::WireFormat::SERIALIZE); @@ -2616,7 +2719,7 @@ void FieldDescriptorProto::SerializeWithCachedSizes( } // optional .google.protobuf.FieldOptions options = 8; - if (_has_bit(7)) { + if (has_options()) { target = ::google::protobuf::internal::WireFormatLite:: WriteMessageNoVirtualToArray( 8, this->options(), target); @@ -2714,28 +2817,28 @@ void FieldDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) { void FieldDescriptorProto::MergeFrom(const FieldDescriptorProto& from) { GOOGLE_CHECK_NE(&from, this); if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (from._has_bit(0)) { + if (from.has_name()) { set_name(from.name()); } - if (from._has_bit(1)) { + if (from.has_number()) { set_number(from.number()); } - if (from._has_bit(2)) { + if (from.has_label()) { set_label(from.label()); } - if (from._has_bit(3)) { + if (from.has_type()) { set_type(from.type()); } - if (from._has_bit(4)) { + if (from.has_type_name()) { set_type_name(from.type_name()); } - if (from._has_bit(5)) { + if (from.has_extendee()) { set_extendee(from.extendee()); } - if (from._has_bit(6)) { + if (from.has_default_value()) { set_default_value(from.default_value()); } - if (from._has_bit(7)) { + if (from.has_options()) { mutable_options()->::google::protobuf::FieldOptions::MergeFrom(from.options()); } } @@ -2789,7 +2892,6 @@ void FieldDescriptorProto::Swap(FieldDescriptorProto* other) { // =================================================================== -const ::std::string EnumDescriptorProto::_default_name_; #ifndef _MSC_VER const int EnumDescriptorProto::kNameFieldNumber; const int EnumDescriptorProto::kValueFieldNumber; @@ -2813,7 +2915,7 @@ EnumDescriptorProto::EnumDescriptorProto(const EnumDescriptorProto& from) void EnumDescriptorProto::SharedCtor() { _cached_size_ = 0; - name_ = const_cast< ::std::string*>(&_default_name_); + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); options_ = NULL; ::memset(_has_bits_, 0, sizeof(_has_bits_)); } @@ -2823,7 +2925,7 @@ EnumDescriptorProto::~EnumDescriptorProto() { } void EnumDescriptorProto::SharedDtor() { - if (name_ != &_default_name_) { + if (name_ != &::google::protobuf::internal::kEmptyString) { delete name_; } if (this != default_instance_) { @@ -2853,12 +2955,12 @@ EnumDescriptorProto* EnumDescriptorProto::New() const { void EnumDescriptorProto::Clear() { if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (_has_bit(0)) { - if (name_ != &_default_name_) { + if (has_name()) { + if (name_ != &::google::protobuf::internal::kEmptyString) { name_->clear(); } } - if (_has_bit(2)) { + if (has_options()) { if (options_ != NULL) options_->::google::protobuf::EnumOptions::Clear(); } } @@ -2936,7 +3038,7 @@ bool EnumDescriptorProto::MergePartialFromCodedStream( void EnumDescriptorProto::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // optional string name = 1; - if (_has_bit(0)) { + if (has_name()) { ::google::protobuf::internal::WireFormat::VerifyUTF8String( this->name().data(), this->name().length(), ::google::protobuf::internal::WireFormat::SERIALIZE); @@ -2951,7 +3053,7 @@ void EnumDescriptorProto::SerializeWithCachedSizes( } // optional .google.protobuf.EnumOptions options = 3; - if (_has_bit(2)) { + if (has_options()) { ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( 3, this->options(), output); } @@ -2965,7 +3067,7 @@ void EnumDescriptorProto::SerializeWithCachedSizes( ::google::protobuf::uint8* EnumDescriptorProto::SerializeWithCachedSizesToArray( ::google::protobuf::uint8* target) const { // optional string name = 1; - if (_has_bit(0)) { + if (has_name()) { ::google::protobuf::internal::WireFormat::VerifyUTF8String( this->name().data(), this->name().length(), ::google::protobuf::internal::WireFormat::SERIALIZE); @@ -2982,7 +3084,7 @@ void EnumDescriptorProto::SerializeWithCachedSizes( } // optional .google.protobuf.EnumOptions options = 3; - if (_has_bit(2)) { + if (has_options()) { target = ::google::protobuf::internal::WireFormatLite:: WriteMessageNoVirtualToArray( 3, this->options(), target); @@ -3049,10 +3151,10 @@ void EnumDescriptorProto::MergeFrom(const EnumDescriptorProto& from) { GOOGLE_CHECK_NE(&from, this); value_.MergeFrom(from.value_); if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (from._has_bit(0)) { + if (from.has_name()) { set_name(from.name()); } - if (from._has_bit(2)) { + if (from.has_options()) { mutable_options()->::google::protobuf::EnumOptions::MergeFrom(from.options()); } } @@ -3104,7 +3206,6 @@ void EnumDescriptorProto::Swap(EnumDescriptorProto* other) { // =================================================================== -const ::std::string EnumValueDescriptorProto::_default_name_; #ifndef _MSC_VER const int EnumValueDescriptorProto::kNameFieldNumber; const int EnumValueDescriptorProto::kNumberFieldNumber; @@ -3128,7 +3229,7 @@ EnumValueDescriptorProto::EnumValueDescriptorProto(const EnumValueDescriptorProt void EnumValueDescriptorProto::SharedCtor() { _cached_size_ = 0; - name_ = const_cast< ::std::string*>(&_default_name_); + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); number_ = 0; options_ = NULL; ::memset(_has_bits_, 0, sizeof(_has_bits_)); @@ -3139,7 +3240,7 @@ EnumValueDescriptorProto::~EnumValueDescriptorProto() { } void EnumValueDescriptorProto::SharedDtor() { - if (name_ != &_default_name_) { + if (name_ != &::google::protobuf::internal::kEmptyString) { delete name_; } if (this != default_instance_) { @@ -3169,13 +3270,13 @@ EnumValueDescriptorProto* EnumValueDescriptorProto::New() const { void EnumValueDescriptorProto::Clear() { if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (_has_bit(0)) { - if (name_ != &_default_name_) { + if (has_name()) { + if (name_ != &::google::protobuf::internal::kEmptyString) { name_->clear(); } } number_ = 0; - if (_has_bit(2)) { + if (has_options()) { if (options_ != NULL) options_->::google::protobuf::EnumValueOptions::Clear(); } } @@ -3213,7 +3314,7 @@ bool EnumValueDescriptorProto::MergePartialFromCodedStream( DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( input, &number_))); - _set_bit(1); + set_has_number(); } else { goto handle_uninterpreted; } @@ -3253,7 +3354,7 @@ bool EnumValueDescriptorProto::MergePartialFromCodedStream( void EnumValueDescriptorProto::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // optional string name = 1; - if (_has_bit(0)) { + if (has_name()) { ::google::protobuf::internal::WireFormat::VerifyUTF8String( this->name().data(), this->name().length(), ::google::protobuf::internal::WireFormat::SERIALIZE); @@ -3262,12 +3363,12 @@ void EnumValueDescriptorProto::SerializeWithCachedSizes( } // optional int32 number = 2; - if (_has_bit(1)) { + if (has_number()) { ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->number(), output); } // optional .google.protobuf.EnumValueOptions options = 3; - if (_has_bit(2)) { + if (has_options()) { ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( 3, this->options(), output); } @@ -3281,7 +3382,7 @@ void EnumValueDescriptorProto::SerializeWithCachedSizes( ::google::protobuf::uint8* EnumValueDescriptorProto::SerializeWithCachedSizesToArray( ::google::protobuf::uint8* target) const { // optional string name = 1; - if (_has_bit(0)) { + if (has_name()) { ::google::protobuf::internal::WireFormat::VerifyUTF8String( this->name().data(), this->name().length(), ::google::protobuf::internal::WireFormat::SERIALIZE); @@ -3291,12 +3392,12 @@ void EnumValueDescriptorProto::SerializeWithCachedSizes( } // optional int32 number = 2; - if (_has_bit(1)) { + if (has_number()) { target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->number(), target); } // optional .google.protobuf.EnumValueOptions options = 3; - if (_has_bit(2)) { + if (has_options()) { target = ::google::protobuf::internal::WireFormatLite:: WriteMessageNoVirtualToArray( 3, this->options(), target); @@ -3361,13 +3462,13 @@ void EnumValueDescriptorProto::MergeFrom(const ::google::protobuf::Message& from void EnumValueDescriptorProto::MergeFrom(const EnumValueDescriptorProto& from) { GOOGLE_CHECK_NE(&from, this); if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (from._has_bit(0)) { + if (from.has_name()) { set_name(from.name()); } - if (from._has_bit(1)) { + if (from.has_number()) { set_number(from.number()); } - if (from._has_bit(2)) { + if (from.has_options()) { mutable_options()->::google::protobuf::EnumValueOptions::MergeFrom(from.options()); } } @@ -3416,7 +3517,6 @@ void EnumValueDescriptorProto::Swap(EnumValueDescriptorProto* other) { // =================================================================== -const ::std::string ServiceDescriptorProto::_default_name_; #ifndef _MSC_VER const int ServiceDescriptorProto::kNameFieldNumber; const int ServiceDescriptorProto::kMethodFieldNumber; @@ -3440,7 +3540,7 @@ ServiceDescriptorProto::ServiceDescriptorProto(const ServiceDescriptorProto& fro void ServiceDescriptorProto::SharedCtor() { _cached_size_ = 0; - name_ = const_cast< ::std::string*>(&_default_name_); + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); options_ = NULL; ::memset(_has_bits_, 0, sizeof(_has_bits_)); } @@ -3450,7 +3550,7 @@ ServiceDescriptorProto::~ServiceDescriptorProto() { } void ServiceDescriptorProto::SharedDtor() { - if (name_ != &_default_name_) { + if (name_ != &::google::protobuf::internal::kEmptyString) { delete name_; } if (this != default_instance_) { @@ -3480,12 +3580,12 @@ ServiceDescriptorProto* ServiceDescriptorProto::New() const { void ServiceDescriptorProto::Clear() { if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (_has_bit(0)) { - if (name_ != &_default_name_) { + if (has_name()) { + if (name_ != &::google::protobuf::internal::kEmptyString) { name_->clear(); } } - if (_has_bit(2)) { + if (has_options()) { if (options_ != NULL) options_->::google::protobuf::ServiceOptions::Clear(); } } @@ -3563,7 +3663,7 @@ bool ServiceDescriptorProto::MergePartialFromCodedStream( void ServiceDescriptorProto::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // optional string name = 1; - if (_has_bit(0)) { + if (has_name()) { ::google::protobuf::internal::WireFormat::VerifyUTF8String( this->name().data(), this->name().length(), ::google::protobuf::internal::WireFormat::SERIALIZE); @@ -3578,7 +3678,7 @@ void ServiceDescriptorProto::SerializeWithCachedSizes( } // optional .google.protobuf.ServiceOptions options = 3; - if (_has_bit(2)) { + if (has_options()) { ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( 3, this->options(), output); } @@ -3592,7 +3692,7 @@ void ServiceDescriptorProto::SerializeWithCachedSizes( ::google::protobuf::uint8* ServiceDescriptorProto::SerializeWithCachedSizesToArray( ::google::protobuf::uint8* target) const { // optional string name = 1; - if (_has_bit(0)) { + if (has_name()) { ::google::protobuf::internal::WireFormat::VerifyUTF8String( this->name().data(), this->name().length(), ::google::protobuf::internal::WireFormat::SERIALIZE); @@ -3609,7 +3709,7 @@ void ServiceDescriptorProto::SerializeWithCachedSizes( } // optional .google.protobuf.ServiceOptions options = 3; - if (_has_bit(2)) { + if (has_options()) { target = ::google::protobuf::internal::WireFormatLite:: WriteMessageNoVirtualToArray( 3, this->options(), target); @@ -3676,10 +3776,10 @@ void ServiceDescriptorProto::MergeFrom(const ServiceDescriptorProto& from) { GOOGLE_CHECK_NE(&from, this); method_.MergeFrom(from.method_); if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (from._has_bit(0)) { + if (from.has_name()) { set_name(from.name()); } - if (from._has_bit(2)) { + if (from.has_options()) { mutable_options()->::google::protobuf::ServiceOptions::MergeFrom(from.options()); } } @@ -3731,9 +3831,6 @@ void ServiceDescriptorProto::Swap(ServiceDescriptorProto* other) { // =================================================================== -const ::std::string MethodDescriptorProto::_default_name_; -const ::std::string MethodDescriptorProto::_default_input_type_; -const ::std::string MethodDescriptorProto::_default_output_type_; #ifndef _MSC_VER const int MethodDescriptorProto::kNameFieldNumber; const int MethodDescriptorProto::kInputTypeFieldNumber; @@ -3758,9 +3855,9 @@ MethodDescriptorProto::MethodDescriptorProto(const MethodDescriptorProto& from) void MethodDescriptorProto::SharedCtor() { _cached_size_ = 0; - name_ = const_cast< ::std::string*>(&_default_name_); - input_type_ = const_cast< ::std::string*>(&_default_input_type_); - output_type_ = const_cast< ::std::string*>(&_default_output_type_); + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + input_type_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + output_type_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); options_ = NULL; ::memset(_has_bits_, 0, sizeof(_has_bits_)); } @@ -3770,13 +3867,13 @@ MethodDescriptorProto::~MethodDescriptorProto() { } void MethodDescriptorProto::SharedDtor() { - if (name_ != &_default_name_) { + if (name_ != &::google::protobuf::internal::kEmptyString) { delete name_; } - if (input_type_ != &_default_input_type_) { + if (input_type_ != &::google::protobuf::internal::kEmptyString) { delete input_type_; } - if (output_type_ != &_default_output_type_) { + if (output_type_ != &::google::protobuf::internal::kEmptyString) { delete output_type_; } if (this != default_instance_) { @@ -3806,22 +3903,22 @@ MethodDescriptorProto* MethodDescriptorProto::New() const { void MethodDescriptorProto::Clear() { if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (_has_bit(0)) { - if (name_ != &_default_name_) { + if (has_name()) { + if (name_ != &::google::protobuf::internal::kEmptyString) { name_->clear(); } } - if (_has_bit(1)) { - if (input_type_ != &_default_input_type_) { + if (has_input_type()) { + if (input_type_ != &::google::protobuf::internal::kEmptyString) { input_type_->clear(); } } - if (_has_bit(2)) { - if (output_type_ != &_default_output_type_) { + if (has_output_type()) { + if (output_type_ != &::google::protobuf::internal::kEmptyString) { output_type_->clear(); } } - if (_has_bit(3)) { + if (has_options()) { if (options_ != NULL) options_->::google::protobuf::MethodOptions::Clear(); } } @@ -3917,7 +4014,7 @@ bool MethodDescriptorProto::MergePartialFromCodedStream( void MethodDescriptorProto::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // optional string name = 1; - if (_has_bit(0)) { + if (has_name()) { ::google::protobuf::internal::WireFormat::VerifyUTF8String( this->name().data(), this->name().length(), ::google::protobuf::internal::WireFormat::SERIALIZE); @@ -3926,7 +4023,7 @@ void MethodDescriptorProto::SerializeWithCachedSizes( } // optional string input_type = 2; - if (_has_bit(1)) { + if (has_input_type()) { ::google::protobuf::internal::WireFormat::VerifyUTF8String( this->input_type().data(), this->input_type().length(), ::google::protobuf::internal::WireFormat::SERIALIZE); @@ -3935,7 +4032,7 @@ void MethodDescriptorProto::SerializeWithCachedSizes( } // optional string output_type = 3; - if (_has_bit(2)) { + if (has_output_type()) { ::google::protobuf::internal::WireFormat::VerifyUTF8String( this->output_type().data(), this->output_type().length(), ::google::protobuf::internal::WireFormat::SERIALIZE); @@ -3944,7 +4041,7 @@ void MethodDescriptorProto::SerializeWithCachedSizes( } // optional .google.protobuf.MethodOptions options = 4; - if (_has_bit(3)) { + if (has_options()) { ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( 4, this->options(), output); } @@ -3958,7 +4055,7 @@ void MethodDescriptorProto::SerializeWithCachedSizes( ::google::protobuf::uint8* MethodDescriptorProto::SerializeWithCachedSizesToArray( ::google::protobuf::uint8* target) const { // optional string name = 1; - if (_has_bit(0)) { + if (has_name()) { ::google::protobuf::internal::WireFormat::VerifyUTF8String( this->name().data(), this->name().length(), ::google::protobuf::internal::WireFormat::SERIALIZE); @@ -3968,7 +4065,7 @@ void MethodDescriptorProto::SerializeWithCachedSizes( } // optional string input_type = 2; - if (_has_bit(1)) { + if (has_input_type()) { ::google::protobuf::internal::WireFormat::VerifyUTF8String( this->input_type().data(), this->input_type().length(), ::google::protobuf::internal::WireFormat::SERIALIZE); @@ -3978,7 +4075,7 @@ void MethodDescriptorProto::SerializeWithCachedSizes( } // optional string output_type = 3; - if (_has_bit(2)) { + if (has_output_type()) { ::google::protobuf::internal::WireFormat::VerifyUTF8String( this->output_type().data(), this->output_type().length(), ::google::protobuf::internal::WireFormat::SERIALIZE); @@ -3988,7 +4085,7 @@ void MethodDescriptorProto::SerializeWithCachedSizes( } // optional .google.protobuf.MethodOptions options = 4; - if (_has_bit(3)) { + if (has_options()) { target = ::google::protobuf::internal::WireFormatLite:: WriteMessageNoVirtualToArray( 4, this->options(), target); @@ -4060,16 +4157,16 @@ void MethodDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) { void MethodDescriptorProto::MergeFrom(const MethodDescriptorProto& from) { GOOGLE_CHECK_NE(&from, this); if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (from._has_bit(0)) { + if (from.has_name()) { set_name(from.name()); } - if (from._has_bit(1)) { + if (from.has_input_type()) { set_input_type(from.input_type()); } - if (from._has_bit(2)) { + if (from.has_output_type()) { set_output_type(from.output_type()); } - if (from._has_bit(3)) { + if (from.has_options()) { mutable_options()->::google::protobuf::MethodOptions::MergeFrom(from.options()); } } @@ -4142,13 +4239,12 @@ const FileOptions_OptimizeMode FileOptions::OptimizeMode_MIN; const FileOptions_OptimizeMode FileOptions::OptimizeMode_MAX; const int FileOptions::OptimizeMode_ARRAYSIZE; #endif // _MSC_VER -const ::std::string FileOptions::_default_java_package_; -const ::std::string FileOptions::_default_java_outer_classname_; #ifndef _MSC_VER const int FileOptions::kJavaPackageFieldNumber; const int FileOptions::kJavaOuterClassnameFieldNumber; const int FileOptions::kJavaMultipleFilesFieldNumber; const int FileOptions::kRetainUnknownFieldsFieldNumber; +const int FileOptions::kJavaGenerateEqualsAndHashFieldNumber; const int FileOptions::kOptimizeForFieldNumber; const int FileOptions::kCcGenericServicesFieldNumber; const int FileOptions::kJavaGenericServicesFieldNumber; @@ -4172,14 +4268,15 @@ FileOptions::FileOptions(const FileOptions& from) void FileOptions::SharedCtor() { _cached_size_ = 0; - java_package_ = const_cast< ::std::string*>(&_default_java_package_); - java_outer_classname_ = const_cast< ::std::string*>(&_default_java_outer_classname_); + java_package_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + java_outer_classname_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); java_multiple_files_ = false; retain_unknown_fields_ = false; + java_generate_equals_and_hash_ = false; optimize_for_ = 1; - cc_generic_services_ = true; - java_generic_services_ = true; - py_generic_services_ = true; + cc_generic_services_ = false; + java_generic_services_ = false; + py_generic_services_ = false; ::memset(_has_bits_, 0, sizeof(_has_bits_)); } @@ -4188,10 +4285,10 @@ FileOptions::~FileOptions() { } void FileOptions::SharedDtor() { - if (java_package_ != &_default_java_package_) { + if (java_package_ != &::google::protobuf::internal::kEmptyString) { delete java_package_; } - if (java_outer_classname_ != &_default_java_outer_classname_) { + if (java_outer_classname_ != &::google::protobuf::internal::kEmptyString) { delete java_outer_classname_; } if (this != default_instance_) { @@ -4221,22 +4318,25 @@ FileOptions* FileOptions::New() const { void FileOptions::Clear() { _extensions_.Clear(); if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (_has_bit(0)) { - if (java_package_ != &_default_java_package_) { + if (has_java_package()) { + if (java_package_ != &::google::protobuf::internal::kEmptyString) { java_package_->clear(); } } - if (_has_bit(1)) { - if (java_outer_classname_ != &_default_java_outer_classname_) { + if (has_java_outer_classname()) { + if (java_outer_classname_ != &::google::protobuf::internal::kEmptyString) { java_outer_classname_->clear(); } } java_multiple_files_ = false; retain_unknown_fields_ = false; + java_generate_equals_and_hash_ = false; optimize_for_ = 1; - cc_generic_services_ = true; - java_generic_services_ = true; - py_generic_services_ = true; + cc_generic_services_ = false; + java_generic_services_ = false; + } + if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) { + py_generic_services_ = false; } uninterpreted_option_.Clear(); ::memset(_has_bits_, 0, sizeof(_has_bits_)); @@ -4311,7 +4411,7 @@ bool FileOptions::MergePartialFromCodedStream( DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( input, &java_multiple_files_))); - _set_bit(2); + set_has_java_multiple_files(); } else { goto handle_uninterpreted; } @@ -4327,7 +4427,7 @@ bool FileOptions::MergePartialFromCodedStream( DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( input, &retain_unknown_fields_))); - _set_bit(3); + set_has_retain_unknown_fields(); } else { goto handle_uninterpreted; } @@ -4335,7 +4435,7 @@ bool FileOptions::MergePartialFromCodedStream( break; } - // optional bool cc_generic_services = 16 [default = true]; + // optional bool cc_generic_services = 16 [default = false]; case 16: { if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { @@ -4343,7 +4443,7 @@ bool FileOptions::MergePartialFromCodedStream( DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( input, &cc_generic_services_))); - _set_bit(5); + set_has_cc_generic_services(); } else { goto handle_uninterpreted; } @@ -4351,7 +4451,7 @@ bool FileOptions::MergePartialFromCodedStream( break; } - // optional bool java_generic_services = 17 [default = true]; + // optional bool java_generic_services = 17 [default = false]; case 17: { if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { @@ -4359,7 +4459,7 @@ bool FileOptions::MergePartialFromCodedStream( DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( input, &java_generic_services_))); - _set_bit(6); + set_has_java_generic_services(); } else { goto handle_uninterpreted; } @@ -4367,7 +4467,7 @@ bool FileOptions::MergePartialFromCodedStream( break; } - // optional bool py_generic_services = 18 [default = true]; + // optional bool py_generic_services = 18 [default = false]; case 18: { if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { @@ -4375,7 +4475,23 @@ bool FileOptions::MergePartialFromCodedStream( DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( input, &py_generic_services_))); - _set_bit(7); + set_has_py_generic_services(); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(160)) goto parse_java_generate_equals_and_hash; + break; + } + + // optional bool java_generate_equals_and_hash = 20 [default = false]; + case 20: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + parse_java_generate_equals_and_hash: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( + input, &java_generate_equals_and_hash_))); + set_has_java_generate_equals_and_hash(); } else { goto handle_uninterpreted; } @@ -4421,7 +4537,7 @@ bool FileOptions::MergePartialFromCodedStream( void FileOptions::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // optional string java_package = 1; - if (_has_bit(0)) { + if (has_java_package()) { ::google::protobuf::internal::WireFormat::VerifyUTF8String( this->java_package().data(), this->java_package().length(), ::google::protobuf::internal::WireFormat::SERIALIZE); @@ -4430,7 +4546,7 @@ void FileOptions::SerializeWithCachedSizes( } // optional string java_outer_classname = 8; - if (_has_bit(1)) { + if (has_java_outer_classname()) { ::google::protobuf::internal::WireFormat::VerifyUTF8String( this->java_outer_classname().data(), this->java_outer_classname().length(), ::google::protobuf::internal::WireFormat::SERIALIZE); @@ -4439,36 +4555,41 @@ void FileOptions::SerializeWithCachedSizes( } // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED]; - if (_has_bit(4)) { + if (has_optimize_for()) { ::google::protobuf::internal::WireFormatLite::WriteEnum( 9, this->optimize_for(), output); } // optional bool java_multiple_files = 10 [default = false]; - if (_has_bit(2)) { + if (has_java_multiple_files()) { ::google::protobuf::internal::WireFormatLite::WriteBool(10, this->java_multiple_files(), output); } // optional bool retain_unknown_fields = 11 [default = false]; - if (_has_bit(3)) { + if (has_retain_unknown_fields()) { ::google::protobuf::internal::WireFormatLite::WriteBool(11, this->retain_unknown_fields(), output); } - // optional bool cc_generic_services = 16 [default = true]; - if (_has_bit(5)) { + // optional bool cc_generic_services = 16 [default = false]; + if (has_cc_generic_services()) { ::google::protobuf::internal::WireFormatLite::WriteBool(16, this->cc_generic_services(), output); } - // optional bool java_generic_services = 17 [default = true]; - if (_has_bit(6)) { + // optional bool java_generic_services = 17 [default = false]; + if (has_java_generic_services()) { ::google::protobuf::internal::WireFormatLite::WriteBool(17, this->java_generic_services(), output); } - // optional bool py_generic_services = 18 [default = true]; - if (_has_bit(7)) { + // optional bool py_generic_services = 18 [default = false]; + if (has_py_generic_services()) { ::google::protobuf::internal::WireFormatLite::WriteBool(18, this->py_generic_services(), output); } + // optional bool java_generate_equals_and_hash = 20 [default = false]; + if (has_java_generate_equals_and_hash()) { + ::google::protobuf::internal::WireFormatLite::WriteBool(20, this->java_generate_equals_and_hash(), output); + } + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; for (int i = 0; i < this->uninterpreted_option_size(); i++) { ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( @@ -4488,7 +4609,7 @@ void FileOptions::SerializeWithCachedSizes( ::google::protobuf::uint8* FileOptions::SerializeWithCachedSizesToArray( ::google::protobuf::uint8* target) const { // optional string java_package = 1; - if (_has_bit(0)) { + if (has_java_package()) { ::google::protobuf::internal::WireFormat::VerifyUTF8String( this->java_package().data(), this->java_package().length(), ::google::protobuf::internal::WireFormat::SERIALIZE); @@ -4498,7 +4619,7 @@ void FileOptions::SerializeWithCachedSizes( } // optional string java_outer_classname = 8; - if (_has_bit(1)) { + if (has_java_outer_classname()) { ::google::protobuf::internal::WireFormat::VerifyUTF8String( this->java_outer_classname().data(), this->java_outer_classname().length(), ::google::protobuf::internal::WireFormat::SERIALIZE); @@ -4508,36 +4629,41 @@ void FileOptions::SerializeWithCachedSizes( } // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED]; - if (_has_bit(4)) { + if (has_optimize_for()) { target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( 9, this->optimize_for(), target); } // optional bool java_multiple_files = 10 [default = false]; - if (_has_bit(2)) { + if (has_java_multiple_files()) { target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(10, this->java_multiple_files(), target); } // optional bool retain_unknown_fields = 11 [default = false]; - if (_has_bit(3)) { + if (has_retain_unknown_fields()) { target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(11, this->retain_unknown_fields(), target); } - // optional bool cc_generic_services = 16 [default = true]; - if (_has_bit(5)) { + // optional bool cc_generic_services = 16 [default = false]; + if (has_cc_generic_services()) { target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(16, this->cc_generic_services(), target); } - // optional bool java_generic_services = 17 [default = true]; - if (_has_bit(6)) { + // optional bool java_generic_services = 17 [default = false]; + if (has_java_generic_services()) { target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(17, this->java_generic_services(), target); } - // optional bool py_generic_services = 18 [default = true]; - if (_has_bit(7)) { + // optional bool py_generic_services = 18 [default = false]; + if (has_py_generic_services()) { target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(18, this->py_generic_services(), target); } + // optional bool java_generate_equals_and_hash = 20 [default = false]; + if (has_java_generate_equals_and_hash()) { + target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(20, this->java_generate_equals_and_hash(), target); + } + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; for (int i = 0; i < this->uninterpreted_option_size(); i++) { target = ::google::protobuf::internal::WireFormatLite:: @@ -4584,23 +4710,30 @@ int FileOptions::ByteSize() const { total_size += 1 + 1; } + // optional bool java_generate_equals_and_hash = 20 [default = false]; + if (has_java_generate_equals_and_hash()) { + total_size += 2 + 1; + } + // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED]; if (has_optimize_for()) { total_size += 1 + ::google::protobuf::internal::WireFormatLite::EnumSize(this->optimize_for()); } - // optional bool cc_generic_services = 16 [default = true]; + // optional bool cc_generic_services = 16 [default = false]; if (has_cc_generic_services()) { total_size += 2 + 1; } - // optional bool java_generic_services = 17 [default = true]; + // optional bool java_generic_services = 17 [default = false]; if (has_java_generic_services()) { total_size += 2 + 1; } - // optional bool py_generic_services = 18 [default = true]; + } + if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) { + // optional bool py_generic_services = 18 [default = false]; if (has_py_generic_services()) { total_size += 2 + 1; } @@ -4643,28 +4776,33 @@ void FileOptions::MergeFrom(const FileOptions& from) { GOOGLE_CHECK_NE(&from, this); uninterpreted_option_.MergeFrom(from.uninterpreted_option_); if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (from._has_bit(0)) { + if (from.has_java_package()) { set_java_package(from.java_package()); } - if (from._has_bit(1)) { + if (from.has_java_outer_classname()) { set_java_outer_classname(from.java_outer_classname()); } - if (from._has_bit(2)) { + if (from.has_java_multiple_files()) { set_java_multiple_files(from.java_multiple_files()); } - if (from._has_bit(3)) { + if (from.has_retain_unknown_fields()) { set_retain_unknown_fields(from.retain_unknown_fields()); } - if (from._has_bit(4)) { + if (from.has_java_generate_equals_and_hash()) { + set_java_generate_equals_and_hash(from.java_generate_equals_and_hash()); + } + if (from.has_optimize_for()) { set_optimize_for(from.optimize_for()); } - if (from._has_bit(5)) { + if (from.has_cc_generic_services()) { set_cc_generic_services(from.cc_generic_services()); } - if (from._has_bit(6)) { + if (from.has_java_generic_services()) { set_java_generic_services(from.java_generic_services()); } - if (from._has_bit(7)) { + } + if (from._has_bits_[8 / 32] & (0xffu << (8 % 32))) { + if (from.has_py_generic_services()) { set_py_generic_services(from.py_generic_services()); } } @@ -4699,6 +4837,7 @@ void FileOptions::Swap(FileOptions* other) { std::swap(java_outer_classname_, other->java_outer_classname_); std::swap(java_multiple_files_, other->java_multiple_files_); std::swap(retain_unknown_fields_, other->retain_unknown_fields_); + std::swap(java_generate_equals_and_hash_, other->java_generate_equals_and_hash_); std::swap(optimize_for_, other->optimize_for_); std::swap(cc_generic_services_, other->cc_generic_services_); std::swap(java_generic_services_, other->java_generic_services_); @@ -4802,7 +4941,7 @@ bool MessageOptions::MergePartialFromCodedStream( DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( input, &message_set_wire_format_))); - _set_bit(0); + set_has_message_set_wire_format(); } else { goto handle_uninterpreted; } @@ -4818,7 +4957,7 @@ bool MessageOptions::MergePartialFromCodedStream( DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( input, &no_standard_descriptor_accessor_))); - _set_bit(1); + set_has_no_standard_descriptor_accessor(); } else { goto handle_uninterpreted; } @@ -4864,12 +5003,12 @@ bool MessageOptions::MergePartialFromCodedStream( void MessageOptions::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // optional bool message_set_wire_format = 1 [default = false]; - if (_has_bit(0)) { + if (has_message_set_wire_format()) { ::google::protobuf::internal::WireFormatLite::WriteBool(1, this->message_set_wire_format(), output); } // optional bool no_standard_descriptor_accessor = 2 [default = false]; - if (_has_bit(1)) { + if (has_no_standard_descriptor_accessor()) { ::google::protobuf::internal::WireFormatLite::WriteBool(2, this->no_standard_descriptor_accessor(), output); } @@ -4892,12 +5031,12 @@ void MessageOptions::SerializeWithCachedSizes( ::google::protobuf::uint8* MessageOptions::SerializeWithCachedSizesToArray( ::google::protobuf::uint8* target) const { // optional bool message_set_wire_format = 1 [default = false]; - if (_has_bit(0)) { + if (has_message_set_wire_format()) { target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(1, this->message_set_wire_format(), target); } // optional bool no_standard_descriptor_accessor = 2 [default = false]; - if (_has_bit(1)) { + if (has_no_standard_descriptor_accessor()) { target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(2, this->no_standard_descriptor_accessor(), target); } @@ -4971,10 +5110,10 @@ void MessageOptions::MergeFrom(const MessageOptions& from) { GOOGLE_CHECK_NE(&from, this); uninterpreted_option_.MergeFrom(from.uninterpreted_option_); if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (from._has_bit(0)) { + if (from.has_message_set_wire_format()) { set_message_set_wire_format(from.message_set_wire_format()); } - if (from._has_bit(1)) { + if (from.has_no_standard_descriptor_accessor()) { set_no_standard_descriptor_accessor(from.no_standard_descriptor_accessor()); } } @@ -5049,7 +5188,6 @@ const FieldOptions_CType FieldOptions::CType_MIN; const FieldOptions_CType FieldOptions::CType_MAX; const int FieldOptions::CType_ARRAYSIZE; #endif // _MSC_VER -const ::std::string FieldOptions::_default_experimental_map_key_; #ifndef _MSC_VER const int FieldOptions::kCtypeFieldNumber; const int FieldOptions::kPackedFieldNumber; @@ -5077,7 +5215,7 @@ void FieldOptions::SharedCtor() { ctype_ = 0; packed_ = false; deprecated_ = false; - experimental_map_key_ = const_cast< ::std::string*>(&_default_experimental_map_key_); + experimental_map_key_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); ::memset(_has_bits_, 0, sizeof(_has_bits_)); } @@ -5086,7 +5224,7 @@ FieldOptions::~FieldOptions() { } void FieldOptions::SharedDtor() { - if (experimental_map_key_ != &_default_experimental_map_key_) { + if (experimental_map_key_ != &::google::protobuf::internal::kEmptyString) { delete experimental_map_key_; } if (this != default_instance_) { @@ -5119,8 +5257,8 @@ void FieldOptions::Clear() { ctype_ = 0; packed_ = false; deprecated_ = false; - if (_has_bit(3)) { - if (experimental_map_key_ != &_default_experimental_map_key_) { + if (has_experimental_map_key()) { + if (experimental_map_key_ != &::google::protobuf::internal::kEmptyString) { experimental_map_key_->clear(); } } @@ -5164,7 +5302,7 @@ bool FieldOptions::MergePartialFromCodedStream( DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( input, &packed_))); - _set_bit(1); + set_has_packed(); } else { goto handle_uninterpreted; } @@ -5180,7 +5318,7 @@ bool FieldOptions::MergePartialFromCodedStream( DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( input, &deprecated_))); - _set_bit(2); + set_has_deprecated(); } else { goto handle_uninterpreted; } @@ -5243,23 +5381,23 @@ bool FieldOptions::MergePartialFromCodedStream( void FieldOptions::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING]; - if (_has_bit(0)) { + if (has_ctype()) { ::google::protobuf::internal::WireFormatLite::WriteEnum( 1, this->ctype(), output); } // optional bool packed = 2; - if (_has_bit(1)) { + if (has_packed()) { ::google::protobuf::internal::WireFormatLite::WriteBool(2, this->packed(), output); } // optional bool deprecated = 3 [default = false]; - if (_has_bit(2)) { + if (has_deprecated()) { ::google::protobuf::internal::WireFormatLite::WriteBool(3, this->deprecated(), output); } // optional string experimental_map_key = 9; - if (_has_bit(3)) { + if (has_experimental_map_key()) { ::google::protobuf::internal::WireFormat::VerifyUTF8String( this->experimental_map_key().data(), this->experimental_map_key().length(), ::google::protobuf::internal::WireFormat::SERIALIZE); @@ -5286,23 +5424,23 @@ void FieldOptions::SerializeWithCachedSizes( ::google::protobuf::uint8* FieldOptions::SerializeWithCachedSizesToArray( ::google::protobuf::uint8* target) const { // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING]; - if (_has_bit(0)) { + if (has_ctype()) { target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( 1, this->ctype(), target); } // optional bool packed = 2; - if (_has_bit(1)) { + if (has_packed()) { target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(2, this->packed(), target); } // optional bool deprecated = 3 [default = false]; - if (_has_bit(2)) { + if (has_deprecated()) { target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(3, this->deprecated(), target); } // optional string experimental_map_key = 9; - if (_has_bit(3)) { + if (has_experimental_map_key()) { ::google::protobuf::internal::WireFormat::VerifyUTF8String( this->experimental_map_key().data(), this->experimental_map_key().length(), ::google::protobuf::internal::WireFormat::SERIALIZE); @@ -5394,16 +5532,16 @@ void FieldOptions::MergeFrom(const FieldOptions& from) { GOOGLE_CHECK_NE(&from, this); uninterpreted_option_.MergeFrom(from.uninterpreted_option_); if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (from._has_bit(0)) { + if (from.has_ctype()) { set_ctype(from.ctype()); } - if (from._has_bit(1)) { + if (from.has_packed()) { set_packed(from.packed()); } - if (from._has_bit(2)) { + if (from.has_deprecated()) { set_deprecated(from.deprecated()); } - if (from._has_bit(3)) { + if (from.has_experimental_map_key()) { set_experimental_map_key(from.experimental_map_key()); } } @@ -6349,7 +6487,6 @@ void MethodOptions::Swap(MethodOptions* other) { // =================================================================== -const ::std::string UninterpretedOption_NamePart::_default_name_part_; #ifndef _MSC_VER const int UninterpretedOption_NamePart::kNamePartFieldNumber; const int UninterpretedOption_NamePart::kIsExtensionFieldNumber; @@ -6371,7 +6508,7 @@ UninterpretedOption_NamePart::UninterpretedOption_NamePart(const UninterpretedOp void UninterpretedOption_NamePart::SharedCtor() { _cached_size_ = 0; - name_part_ = const_cast< ::std::string*>(&_default_name_part_); + name_part_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); is_extension_ = false; ::memset(_has_bits_, 0, sizeof(_has_bits_)); } @@ -6381,7 +6518,7 @@ UninterpretedOption_NamePart::~UninterpretedOption_NamePart() { } void UninterpretedOption_NamePart::SharedDtor() { - if (name_part_ != &_default_name_part_) { + if (name_part_ != &::google::protobuf::internal::kEmptyString) { delete name_part_; } if (this != default_instance_) { @@ -6410,8 +6547,8 @@ UninterpretedOption_NamePart* UninterpretedOption_NamePart::New() const { void UninterpretedOption_NamePart::Clear() { if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (_has_bit(0)) { - if (name_part_ != &_default_name_part_) { + if (has_name_part()) { + if (name_part_ != &::google::protobuf::internal::kEmptyString) { name_part_->clear(); } } @@ -6451,7 +6588,7 @@ bool UninterpretedOption_NamePart::MergePartialFromCodedStream( DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( input, &is_extension_))); - _set_bit(1); + set_has_is_extension(); } else { goto handle_uninterpreted; } @@ -6477,7 +6614,7 @@ bool UninterpretedOption_NamePart::MergePartialFromCodedStream( void UninterpretedOption_NamePart::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // required string name_part = 1; - if (_has_bit(0)) { + if (has_name_part()) { ::google::protobuf::internal::WireFormat::VerifyUTF8String( this->name_part().data(), this->name_part().length(), ::google::protobuf::internal::WireFormat::SERIALIZE); @@ -6486,7 +6623,7 @@ void UninterpretedOption_NamePart::SerializeWithCachedSizes( } // required bool is_extension = 2; - if (_has_bit(1)) { + if (has_is_extension()) { ::google::protobuf::internal::WireFormatLite::WriteBool(2, this->is_extension(), output); } @@ -6499,7 +6636,7 @@ void UninterpretedOption_NamePart::SerializeWithCachedSizes( ::google::protobuf::uint8* UninterpretedOption_NamePart::SerializeWithCachedSizesToArray( ::google::protobuf::uint8* target) const { // required string name_part = 1; - if (_has_bit(0)) { + if (has_name_part()) { ::google::protobuf::internal::WireFormat::VerifyUTF8String( this->name_part().data(), this->name_part().length(), ::google::protobuf::internal::WireFormat::SERIALIZE); @@ -6509,7 +6646,7 @@ void UninterpretedOption_NamePart::SerializeWithCachedSizes( } // required bool is_extension = 2; - if (_has_bit(1)) { + if (has_is_extension()) { target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(2, this->is_extension(), target); } @@ -6563,10 +6700,10 @@ void UninterpretedOption_NamePart::MergeFrom(const ::google::protobuf::Message& void UninterpretedOption_NamePart::MergeFrom(const UninterpretedOption_NamePart& from) { GOOGLE_CHECK_NE(&from, this); if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { - if (from._has_bit(0)) { + if (from.has_name_part()) { set_name_part(from.name_part()); } - if (from._has_bit(1)) { + if (from.has_is_extension()) { set_is_extension(from.is_extension()); } } @@ -6612,8 +6749,6 @@ void UninterpretedOption_NamePart::Swap(UninterpretedOption_NamePart* other) { // ------------------------------------------------------------------- -const ::std::string UninterpretedOption::_default_identifier_value_; -const ::std::string UninterpretedOption::_default_string_value_; #ifndef _MSC_VER const int UninterpretedOption::kNameFieldNumber; const int UninterpretedOption::kIdentifierValueFieldNumber; @@ -6621,6 +6756,7 @@ const int UninterpretedOption::kPositiveIntValueFieldNumber; const int UninterpretedOption::kNegativeIntValueFieldNumber; const int UninterpretedOption::kDoubleValueFieldNumber; const int UninterpretedOption::kStringValueFieldNumber; +const int UninterpretedOption::kAggregateValueFieldNumber; #endif // !_MSC_VER UninterpretedOption::UninterpretedOption() @@ -6639,11 +6775,12 @@ UninterpretedOption::UninterpretedOption(const UninterpretedOption& from) void UninterpretedOption::SharedCtor() { _cached_size_ = 0; - identifier_value_ = const_cast< ::std::string*>(&_default_identifier_value_); + identifier_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); positive_int_value_ = GOOGLE_ULONGLONG(0); negative_int_value_ = GOOGLE_LONGLONG(0); double_value_ = 0; - string_value_ = const_cast< ::std::string*>(&_default_string_value_); + string_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + aggregate_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); ::memset(_has_bits_, 0, sizeof(_has_bits_)); } @@ -6652,12 +6789,15 @@ UninterpretedOption::~UninterpretedOption() { } void UninterpretedOption::SharedDtor() { - if (identifier_value_ != &_default_identifier_value_) { + if (identifier_value_ != &::google::protobuf::internal::kEmptyString) { delete identifier_value_; } - if (string_value_ != &_default_string_value_) { + if (string_value_ != &::google::protobuf::internal::kEmptyString) { delete string_value_; } + if (aggregate_value_ != &::google::protobuf::internal::kEmptyString) { + delete aggregate_value_; + } if (this != default_instance_) { } } @@ -6684,19 +6824,24 @@ UninterpretedOption* UninterpretedOption::New() const { void UninterpretedOption::Clear() { if (_has_bits_[1 / 32] & (0xffu << (1 % 32))) { - if (_has_bit(1)) { - if (identifier_value_ != &_default_identifier_value_) { + if (has_identifier_value()) { + if (identifier_value_ != &::google::protobuf::internal::kEmptyString) { identifier_value_->clear(); } } positive_int_value_ = GOOGLE_ULONGLONG(0); negative_int_value_ = GOOGLE_LONGLONG(0); double_value_ = 0; - if (_has_bit(5)) { - if (string_value_ != &_default_string_value_) { + if (has_string_value()) { + if (string_value_ != &::google::protobuf::internal::kEmptyString) { string_value_->clear(); } } + if (has_aggregate_value()) { + if (aggregate_value_ != &::google::protobuf::internal::kEmptyString) { + aggregate_value_->clear(); + } + } } name_.Clear(); ::memset(_has_bits_, 0, sizeof(_has_bits_)); @@ -6749,7 +6894,7 @@ bool UninterpretedOption::MergePartialFromCodedStream( DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( input, &positive_int_value_))); - _set_bit(2); + set_has_positive_int_value(); } else { goto handle_uninterpreted; } @@ -6765,7 +6910,7 @@ bool UninterpretedOption::MergePartialFromCodedStream( DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>( input, &negative_int_value_))); - _set_bit(3); + set_has_negative_int_value(); } else { goto handle_uninterpreted; } @@ -6781,7 +6926,7 @@ bool UninterpretedOption::MergePartialFromCodedStream( DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< double, ::google::protobuf::internal::WireFormatLite::TYPE_DOUBLE>( input, &double_value_))); - _set_bit(4); + set_has_double_value(); } else { goto handle_uninterpreted; } @@ -6799,6 +6944,23 @@ bool UninterpretedOption::MergePartialFromCodedStream( } else { goto handle_uninterpreted; } + if (input->ExpectTag(66)) goto parse_aggregate_value; + break; + } + + // optional string aggregate_value = 8; + case 8: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_aggregate_value: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_aggregate_value())); + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->aggregate_value().data(), this->aggregate_value().length(), + ::google::protobuf::internal::WireFormat::PARSE); + } else { + goto handle_uninterpreted; + } if (input->ExpectAtEnd()) return true; break; } @@ -6827,7 +6989,7 @@ void UninterpretedOption::SerializeWithCachedSizes( } // optional string identifier_value = 3; - if (_has_bit(1)) { + if (has_identifier_value()) { ::google::protobuf::internal::WireFormat::VerifyUTF8String( this->identifier_value().data(), this->identifier_value().length(), ::google::protobuf::internal::WireFormat::SERIALIZE); @@ -6836,26 +6998,35 @@ void UninterpretedOption::SerializeWithCachedSizes( } // optional uint64 positive_int_value = 4; - if (_has_bit(2)) { + if (has_positive_int_value()) { ::google::protobuf::internal::WireFormatLite::WriteUInt64(4, this->positive_int_value(), output); } // optional int64 negative_int_value = 5; - if (_has_bit(3)) { + if (has_negative_int_value()) { ::google::protobuf::internal::WireFormatLite::WriteInt64(5, this->negative_int_value(), output); } // optional double double_value = 6; - if (_has_bit(4)) { + if (has_double_value()) { ::google::protobuf::internal::WireFormatLite::WriteDouble(6, this->double_value(), output); } // optional bytes string_value = 7; - if (_has_bit(5)) { + if (has_string_value()) { ::google::protobuf::internal::WireFormatLite::WriteBytes( 7, this->string_value(), output); } + // optional string aggregate_value = 8; + if (has_aggregate_value()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->aggregate_value().data(), this->aggregate_value().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + ::google::protobuf::internal::WireFormatLite::WriteString( + 8, this->aggregate_value(), output); + } + if (!unknown_fields().empty()) { ::google::protobuf::internal::WireFormatLite::SerializeUnknownFields( unknown_fields(), output); @@ -6872,7 +7043,7 @@ void UninterpretedOption::SerializeWithCachedSizes( } // optional string identifier_value = 3; - if (_has_bit(1)) { + if (has_identifier_value()) { ::google::protobuf::internal::WireFormat::VerifyUTF8String( this->identifier_value().data(), this->identifier_value().length(), ::google::protobuf::internal::WireFormat::SERIALIZE); @@ -6882,27 +7053,37 @@ void UninterpretedOption::SerializeWithCachedSizes( } // optional uint64 positive_int_value = 4; - if (_has_bit(2)) { + if (has_positive_int_value()) { target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(4, this->positive_int_value(), target); } // optional int64 negative_int_value = 5; - if (_has_bit(3)) { + if (has_negative_int_value()) { target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(5, this->negative_int_value(), target); } // optional double double_value = 6; - if (_has_bit(4)) { + if (has_double_value()) { target = ::google::protobuf::internal::WireFormatLite::WriteDoubleToArray(6, this->double_value(), target); } // optional bytes string_value = 7; - if (_has_bit(5)) { + if (has_string_value()) { target = ::google::protobuf::internal::WireFormatLite::WriteBytesToArray( 7, this->string_value(), target); } + // optional string aggregate_value = 8; + if (has_aggregate_value()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8String( + this->aggregate_value().data(), this->aggregate_value().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 8, this->aggregate_value(), target); + } + if (!unknown_fields().empty()) { target = ::google::protobuf::internal::WireFormatLite::SerializeUnknownFieldsToArray( unknown_fields(), target); @@ -6947,6 +7128,13 @@ int UninterpretedOption::ByteSize() const { this->string_value()); } + // optional string aggregate_value = 8; + if (has_aggregate_value()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->aggregate_value()); + } + } // repeated .google.protobuf.UninterpretedOption.NamePart name = 2; total_size += 1 * this->name_size(); @@ -6983,21 +7171,24 @@ void UninterpretedOption::MergeFrom(const UninterpretedOption& from) { GOOGLE_CHECK_NE(&from, this); name_.MergeFrom(from.name_); if (from._has_bits_[1 / 32] & (0xffu << (1 % 32))) { - if (from._has_bit(1)) { + if (from.has_identifier_value()) { set_identifier_value(from.identifier_value()); } - if (from._has_bit(2)) { + if (from.has_positive_int_value()) { set_positive_int_value(from.positive_int_value()); } - if (from._has_bit(3)) { + if (from.has_negative_int_value()) { set_negative_int_value(from.negative_int_value()); } - if (from._has_bit(4)) { + if (from.has_double_value()) { set_double_value(from.double_value()); } - if (from._has_bit(5)) { + if (from.has_string_value()) { set_string_value(from.string_value()); } + if (from.has_aggregate_value()) { + set_aggregate_value(from.aggregate_value()); + } } mutable_unknown_fields()->MergeFrom(from.unknown_fields()); } @@ -7030,6 +7221,7 @@ void UninterpretedOption::Swap(UninterpretedOption* other) { std::swap(negative_int_value_, other->negative_int_value_); std::swap(double_value_, other->double_value_); std::swap(string_value_, other->string_value_); + std::swap(aggregate_value_, other->aggregate_value_); std::swap(_has_bits_[0], other->_has_bits_[0]); _unknown_fields_.Swap(&other->_unknown_fields_); std::swap(_cached_size_, other->_cached_size_); @@ -7045,6 +7237,495 @@ void UninterpretedOption::Swap(UninterpretedOption* other) { } +// =================================================================== + +#ifndef _MSC_VER +const int SourceCodeInfo_Location::kPathFieldNumber; +const int SourceCodeInfo_Location::kSpanFieldNumber; +#endif // !_MSC_VER + +SourceCodeInfo_Location::SourceCodeInfo_Location() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void SourceCodeInfo_Location::InitAsDefaultInstance() { +} + +SourceCodeInfo_Location::SourceCodeInfo_Location(const SourceCodeInfo_Location& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void SourceCodeInfo_Location::SharedCtor() { + _cached_size_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +SourceCodeInfo_Location::~SourceCodeInfo_Location() { + SharedDtor(); +} + +void SourceCodeInfo_Location::SharedDtor() { + if (this != default_instance_) { + } +} + +void SourceCodeInfo_Location::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* SourceCodeInfo_Location::descriptor() { + protobuf_AssignDescriptorsOnce(); + return SourceCodeInfo_Location_descriptor_; +} + +const SourceCodeInfo_Location& SourceCodeInfo_Location::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); return *default_instance_; +} + +SourceCodeInfo_Location* SourceCodeInfo_Location::default_instance_ = NULL; + +SourceCodeInfo_Location* SourceCodeInfo_Location::New() const { + return new SourceCodeInfo_Location; +} + +void SourceCodeInfo_Location::Clear() { + path_.Clear(); + span_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool SourceCodeInfo_Location::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // repeated int32 path = 1 [packed = true]; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, this->mutable_path()))); + } else if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) + == ::google::protobuf::internal::WireFormatLite:: + WIRETYPE_VARINT) { + DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + 1, 10, input, this->mutable_path()))); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(18)) goto parse_span; + break; + } + + // repeated int32 span = 2 [packed = true]; + case 2: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_span: + DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, this->mutable_span()))); + } else if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) + == ::google::protobuf::internal::WireFormatLite:: + WIRETYPE_VARINT) { + DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + 1, 18, input, this->mutable_span()))); + } else { + goto handle_uninterpreted; + } + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void SourceCodeInfo_Location::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // repeated int32 path = 1 [packed = true]; + if (this->path_size() > 0) { + ::google::protobuf::internal::WireFormatLite::WriteTag(1, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output); + output->WriteVarint32(_path_cached_byte_size_); + } + for (int i = 0; i < this->path_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteInt32NoTag( + this->path(i), output); + } + + // repeated int32 span = 2 [packed = true]; + if (this->span_size() > 0) { + ::google::protobuf::internal::WireFormatLite::WriteTag(2, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output); + output->WriteVarint32(_span_cached_byte_size_); + } + for (int i = 0; i < this->span_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteInt32NoTag( + this->span(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormatLite::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* SourceCodeInfo_Location::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // repeated int32 path = 1 [packed = true]; + if (this->path_size() > 0) { + target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray( + 1, + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, + target); + target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray( + _path_cached_byte_size_, target); + } + for (int i = 0; i < this->path_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteInt32NoTagToArray(this->path(i), target); + } + + // repeated int32 span = 2 [packed = true]; + if (this->span_size() > 0) { + target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray( + 2, + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, + target); + target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray( + _span_cached_byte_size_, target); + } + for (int i = 0; i < this->span_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteInt32NoTagToArray(this->span(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormatLite::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int SourceCodeInfo_Location::ByteSize() const { + int total_size = 0; + + // repeated int32 path = 1 [packed = true]; + { + int data_size = 0; + for (int i = 0; i < this->path_size(); i++) { + data_size += ::google::protobuf::internal::WireFormatLite:: + Int32Size(this->path(i)); + } + if (data_size > 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size(data_size); + } + _path_cached_byte_size_ = data_size; + total_size += data_size; + } + + // repeated int32 span = 2 [packed = true]; + { + int data_size = 0; + for (int i = 0; i < this->span_size(); i++) { + data_size += ::google::protobuf::internal::WireFormatLite:: + Int32Size(this->span(i)); + } + if (data_size > 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size(data_size); + } + _span_cached_byte_size_ = data_size; + total_size += data_size; + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormatLite::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void SourceCodeInfo_Location::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const SourceCodeInfo_Location* source = + ::google::protobuf::internal::dynamic_cast_if_available<const SourceCodeInfo_Location*>( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void SourceCodeInfo_Location::MergeFrom(const SourceCodeInfo_Location& from) { + GOOGLE_CHECK_NE(&from, this); + path_.MergeFrom(from.path_); + span_.MergeFrom(from.span_); + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void SourceCodeInfo_Location::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void SourceCodeInfo_Location::CopyFrom(const SourceCodeInfo_Location& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool SourceCodeInfo_Location::IsInitialized() const { + + return true; +} + +void SourceCodeInfo_Location::Swap(SourceCodeInfo_Location* other) { + if (other != this) { + path_.Swap(&other->path_); + span_.Swap(&other->span_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata SourceCodeInfo_Location::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = SourceCodeInfo_Location_descriptor_; + metadata.reflection = SourceCodeInfo_Location_reflection_; + return metadata; +} + + +// ------------------------------------------------------------------- + +#ifndef _MSC_VER +const int SourceCodeInfo::kLocationFieldNumber; +#endif // !_MSC_VER + +SourceCodeInfo::SourceCodeInfo() + : ::google::protobuf::Message() { + SharedCtor(); +} + +void SourceCodeInfo::InitAsDefaultInstance() { +} + +SourceCodeInfo::SourceCodeInfo(const SourceCodeInfo& from) + : ::google::protobuf::Message() { + SharedCtor(); + MergeFrom(from); +} + +void SourceCodeInfo::SharedCtor() { + _cached_size_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +SourceCodeInfo::~SourceCodeInfo() { + SharedDtor(); +} + +void SourceCodeInfo::SharedDtor() { + if (this != default_instance_) { + } +} + +void SourceCodeInfo::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* SourceCodeInfo::descriptor() { + protobuf_AssignDescriptorsOnce(); + return SourceCodeInfo_descriptor_; +} + +const SourceCodeInfo& SourceCodeInfo::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); return *default_instance_; +} + +SourceCodeInfo* SourceCodeInfo::default_instance_ = NULL; + +SourceCodeInfo* SourceCodeInfo::New() const { + return new SourceCodeInfo; +} + +void SourceCodeInfo::Clear() { + location_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->Clear(); +} + +bool SourceCodeInfo::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) return false + ::google::protobuf::uint32 tag; + while ((tag = input->ReadTag()) != 0) { + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // repeated .google.protobuf.SourceCodeInfo.Location location = 1; + case 1: { + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + parse_location: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_location())); + } else { + goto handle_uninterpreted; + } + if (input->ExpectTag(10)) goto parse_location; + if (input->ExpectAtEnd()) return true; + break; + } + + default: { + handle_uninterpreted: + if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + return true; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag, mutable_unknown_fields())); + break; + } + } + } + return true; +#undef DO_ +} + +void SourceCodeInfo::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // repeated .google.protobuf.SourceCodeInfo.Location location = 1; + for (int i = 0; i < this->location_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->location(i), output); + } + + if (!unknown_fields().empty()) { + ::google::protobuf::internal::WireFormatLite::SerializeUnknownFields( + unknown_fields(), output); + } +} + +::google::protobuf::uint8* SourceCodeInfo::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // repeated .google.protobuf.SourceCodeInfo.Location location = 1; + for (int i = 0; i < this->location_size(); i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->location(i), target); + } + + if (!unknown_fields().empty()) { + target = ::google::protobuf::internal::WireFormatLite::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + return target; +} + +int SourceCodeInfo::ByteSize() const { + int total_size = 0; + + // repeated .google.protobuf.SourceCodeInfo.Location location = 1; + total_size += 1 * this->location_size(); + for (int i = 0; i < this->location_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->location(i)); + } + + if (!unknown_fields().empty()) { + total_size += + ::google::protobuf::internal::WireFormatLite::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void SourceCodeInfo::MergeFrom(const ::google::protobuf::Message& from) { + GOOGLE_CHECK_NE(&from, this); + const SourceCodeInfo* source = + ::google::protobuf::internal::dynamic_cast_if_available<const SourceCodeInfo*>( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void SourceCodeInfo::MergeFrom(const SourceCodeInfo& from) { + GOOGLE_CHECK_NE(&from, this); + location_.MergeFrom(from.location_); + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); +} + +void SourceCodeInfo::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void SourceCodeInfo::CopyFrom(const SourceCodeInfo& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool SourceCodeInfo::IsInitialized() const { + + return true; +} + +void SourceCodeInfo::Swap(SourceCodeInfo* other) { + if (other != this) { + location_.Swap(&other->location_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.Swap(&other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::google::protobuf::Metadata SourceCodeInfo::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = SourceCodeInfo_descriptor_; + metadata.reflection = SourceCodeInfo_reflection_; + return metadata; +} + + // @@protoc_insertion_point(namespace_scope) } // namespace protobuf diff --git a/third_party/protobuf/src/google/protobuf/descriptor.pb.h b/third_party/protobuf/src/google/protobuf/descriptor.pb.h index 217e588..cf7a374 100644 --- a/third_party/protobuf/src/google/protobuf/descriptor.pb.h +++ b/third_party/protobuf/src/google/protobuf/descriptor.pb.h @@ -8,12 +8,12 @@ #include <google/protobuf/stubs/common.h> -#if GOOGLE_PROTOBUF_VERSION < 2003000 +#if GOOGLE_PROTOBUF_VERSION < 2004000 #error This file was generated by a newer version of protoc which is #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 2003001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#if 2004000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc. @@ -22,6 +22,7 @@ #include <google/protobuf/generated_message_util.h> #include <google/protobuf/repeated_field.h> #include <google/protobuf/extension_set.h> +#include <google/protobuf/unknown_field_set.h> #include <google/protobuf/generated_message_reflection.h> // @@protoc_insertion_point(includes) @@ -51,6 +52,8 @@ class ServiceOptions; class MethodOptions; class UninterpretedOption; class UninterpretedOption_NamePart; +class SourceCodeInfo; +class SourceCodeInfo_Location; enum FieldDescriptorProto_Type { FieldDescriptorProto_Type_TYPE_DOUBLE = 1, @@ -217,26 +220,17 @@ class LIBPROTOBUF_EXPORT FileDescriptorSet : public ::google::protobuf::Message // @@protoc_insertion_point(class_scope:google.protobuf.FileDescriptorSet) private: + ::google::protobuf::UnknownFieldSet _unknown_fields_; - mutable int _cached_size_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto > file_; - friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + mutable int _cached_size_; ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; - // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? - inline bool _has_bit(int index) const { - return (_has_bits_[index / 32] & (1u << (index % 32))) != 0; - } - inline void _set_bit(int index) { - _has_bits_[index / 32] |= (1u << (index % 32)); - } - inline void _clear_bit(int index) { - _has_bits_[index / 32] &= ~(1u << (index % 32)); - } + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); void InitAsDefaultInstance(); static FileDescriptorSet* default_instance_; @@ -306,6 +300,7 @@ class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Messag inline void set_name(const char* value); inline void set_name(const char* value, size_t size); inline ::std::string* mutable_name(); + inline ::std::string* release_name(); // optional string package = 2; inline bool has_package() const; @@ -316,6 +311,7 @@ class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Messag inline void set_package(const char* value); inline void set_package(const char* value, size_t size); inline ::std::string* mutable_package(); + inline ::std::string* release_package(); // repeated string dependency = 3; inline int dependency_size() const; @@ -387,39 +383,46 @@ class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Messag static const int kOptionsFieldNumber = 8; inline const ::google::protobuf::FileOptions& options() const; inline ::google::protobuf::FileOptions* mutable_options(); + inline ::google::protobuf::FileOptions* release_options(); + + // optional .google.protobuf.SourceCodeInfo source_code_info = 9; + inline bool has_source_code_info() const; + inline void clear_source_code_info(); + static const int kSourceCodeInfoFieldNumber = 9; + inline const ::google::protobuf::SourceCodeInfo& source_code_info() const; + inline ::google::protobuf::SourceCodeInfo* mutable_source_code_info(); + inline ::google::protobuf::SourceCodeInfo* release_source_code_info(); // @@protoc_insertion_point(class_scope:google.protobuf.FileDescriptorProto) private: + inline void set_has_name(); + inline void clear_has_name(); + inline void set_has_package(); + inline void clear_has_package(); + inline void set_has_options(); + inline void clear_has_options(); + inline void set_has_source_code_info(); + inline void clear_has_source_code_info(); + ::google::protobuf::UnknownFieldSet _unknown_fields_; - mutable int _cached_size_; ::std::string* name_; - static const ::std::string _default_name_; ::std::string* package_; - static const ::std::string _default_package_; ::google::protobuf::RepeatedPtrField< ::std::string> dependency_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto > message_type_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto > enum_type_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto > service_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto > extension_; ::google::protobuf::FileOptions* options_; + ::google::protobuf::SourceCodeInfo* source_code_info_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(9 + 31) / 32]; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); - ::google::protobuf::uint32 _has_bits_[(8 + 31) / 32]; - - // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? - inline bool _has_bit(int index) const { - return (_has_bits_[index / 32] & (1u << (index % 32))) != 0; - } - inline void _set_bit(int index) { - _has_bits_[index / 32] |= (1u << (index % 32)); - } - inline void _clear_bit(int index) { - _has_bits_[index / 32] &= ~(1u << (index % 32)); - } - void InitAsDefaultInstance(); static FileDescriptorProto* default_instance_; }; @@ -495,27 +498,22 @@ class LIBPROTOBUF_EXPORT DescriptorProto_ExtensionRange : public ::google::proto // @@protoc_insertion_point(class_scope:google.protobuf.DescriptorProto.ExtensionRange) private: + inline void set_has_start(); + inline void clear_has_start(); + inline void set_has_end(); + inline void clear_has_end(); + ::google::protobuf::UnknownFieldSet _unknown_fields_; - mutable int _cached_size_; ::google::protobuf::int32 start_; ::google::protobuf::int32 end_; - friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + mutable int _cached_size_; ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; - // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? - inline bool _has_bit(int index) const { - return (_has_bits_[index / 32] & (1u << (index % 32))) != 0; - } - inline void _set_bit(int index) { - _has_bits_[index / 32] |= (1u << (index % 32)); - } - inline void _clear_bit(int index) { - _has_bits_[index / 32] &= ~(1u << (index % 32)); - } + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); void InitAsDefaultInstance(); static DescriptorProto_ExtensionRange* default_instance_; @@ -587,6 +585,7 @@ class LIBPROTOBUF_EXPORT DescriptorProto : public ::google::protobuf::Message { inline void set_name(const char* value); inline void set_name(const char* value, size_t size); inline ::std::string* mutable_name(); + inline ::std::string* release_name(); // repeated .google.protobuf.FieldDescriptorProto field = 2; inline int field_size() const; @@ -654,36 +653,31 @@ class LIBPROTOBUF_EXPORT DescriptorProto : public ::google::protobuf::Message { static const int kOptionsFieldNumber = 7; inline const ::google::protobuf::MessageOptions& options() const; inline ::google::protobuf::MessageOptions* mutable_options(); + inline ::google::protobuf::MessageOptions* release_options(); // @@protoc_insertion_point(class_scope:google.protobuf.DescriptorProto) private: + inline void set_has_name(); + inline void clear_has_name(); + inline void set_has_options(); + inline void clear_has_options(); + ::google::protobuf::UnknownFieldSet _unknown_fields_; - mutable int _cached_size_; ::std::string* name_; - static const ::std::string _default_name_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto > field_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto > extension_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto > nested_type_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto > enum_type_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange > extension_range_; ::google::protobuf::MessageOptions* options_; - friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + mutable int _cached_size_; ::google::protobuf::uint32 _has_bits_[(7 + 31) / 32]; - // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? - inline bool _has_bit(int index) const { - return (_has_bits_[index / 32] & (1u << (index % 32))) != 0; - } - inline void _set_bit(int index) { - _has_bits_[index / 32] |= (1u << (index % 32)); - } - inline void _clear_bit(int index) { - _has_bits_[index / 32] &= ~(1u << (index % 32)); - } + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); void InitAsDefaultInstance(); static DescriptorProto* default_instance_; @@ -818,6 +812,7 @@ class LIBPROTOBUF_EXPORT FieldDescriptorProto : public ::google::protobuf::Messa inline void set_name(const char* value); inline void set_name(const char* value, size_t size); inline ::std::string* mutable_name(); + inline ::std::string* release_name(); // optional int32 number = 3; inline bool has_number() const; @@ -849,6 +844,7 @@ class LIBPROTOBUF_EXPORT FieldDescriptorProto : public ::google::protobuf::Messa inline void set_type_name(const char* value); inline void set_type_name(const char* value, size_t size); inline ::std::string* mutable_type_name(); + inline ::std::string* release_type_name(); // optional string extendee = 2; inline bool has_extendee() const; @@ -859,6 +855,7 @@ class LIBPROTOBUF_EXPORT FieldDescriptorProto : public ::google::protobuf::Messa inline void set_extendee(const char* value); inline void set_extendee(const char* value, size_t size); inline ::std::string* mutable_extendee(); + inline ::std::string* release_extendee(); // optional string default_value = 7; inline bool has_default_value() const; @@ -869,6 +866,7 @@ class LIBPROTOBUF_EXPORT FieldDescriptorProto : public ::google::protobuf::Messa inline void set_default_value(const char* value); inline void set_default_value(const char* value, size_t size); inline ::std::string* mutable_default_value(); + inline ::std::string* release_default_value(); // optional .google.protobuf.FieldOptions options = 8; inline bool has_options() const; @@ -876,40 +874,44 @@ class LIBPROTOBUF_EXPORT FieldDescriptorProto : public ::google::protobuf::Messa static const int kOptionsFieldNumber = 8; inline const ::google::protobuf::FieldOptions& options() const; inline ::google::protobuf::FieldOptions* mutable_options(); + inline ::google::protobuf::FieldOptions* release_options(); // @@protoc_insertion_point(class_scope:google.protobuf.FieldDescriptorProto) private: + inline void set_has_name(); + inline void clear_has_name(); + inline void set_has_number(); + inline void clear_has_number(); + inline void set_has_label(); + inline void clear_has_label(); + inline void set_has_type(); + inline void clear_has_type(); + inline void set_has_type_name(); + inline void clear_has_type_name(); + inline void set_has_extendee(); + inline void clear_has_extendee(); + inline void set_has_default_value(); + inline void clear_has_default_value(); + inline void set_has_options(); + inline void clear_has_options(); + ::google::protobuf::UnknownFieldSet _unknown_fields_; - mutable int _cached_size_; ::std::string* name_; - static const ::std::string _default_name_; ::google::protobuf::int32 number_; int label_; - int type_; ::std::string* type_name_; - static const ::std::string _default_type_name_; ::std::string* extendee_; - static const ::std::string _default_extendee_; ::std::string* default_value_; - static const ::std::string _default_default_value_; ::google::protobuf::FieldOptions* options_; - friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + int type_; + mutable int _cached_size_; ::google::protobuf::uint32 _has_bits_[(8 + 31) / 32]; - // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? - inline bool _has_bit(int index) const { - return (_has_bits_[index / 32] & (1u << (index % 32))) != 0; - } - inline void _set_bit(int index) { - _has_bits_[index / 32] |= (1u << (index % 32)); - } - inline void _clear_bit(int index) { - _has_bits_[index / 32] &= ~(1u << (index % 32)); - } + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); void InitAsDefaultInstance(); static FieldDescriptorProto* default_instance_; @@ -979,6 +981,7 @@ class LIBPROTOBUF_EXPORT EnumDescriptorProto : public ::google::protobuf::Messag inline void set_name(const char* value); inline void set_name(const char* value, size_t size); inline ::std::string* mutable_name(); + inline ::std::string* release_name(); // repeated .google.protobuf.EnumValueDescriptorProto value = 2; inline int value_size() const; @@ -998,32 +1001,27 @@ class LIBPROTOBUF_EXPORT EnumDescriptorProto : public ::google::protobuf::Messag static const int kOptionsFieldNumber = 3; inline const ::google::protobuf::EnumOptions& options() const; inline ::google::protobuf::EnumOptions* mutable_options(); + inline ::google::protobuf::EnumOptions* release_options(); // @@protoc_insertion_point(class_scope:google.protobuf.EnumDescriptorProto) private: + inline void set_has_name(); + inline void clear_has_name(); + inline void set_has_options(); + inline void clear_has_options(); + ::google::protobuf::UnknownFieldSet _unknown_fields_; - mutable int _cached_size_; ::std::string* name_; - static const ::std::string _default_name_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto > value_; ::google::protobuf::EnumOptions* options_; - friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + mutable int _cached_size_; ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32]; - // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? - inline bool _has_bit(int index) const { - return (_has_bits_[index / 32] & (1u << (index % 32))) != 0; - } - inline void _set_bit(int index) { - _has_bits_[index / 32] |= (1u << (index % 32)); - } - inline void _clear_bit(int index) { - _has_bits_[index / 32] &= ~(1u << (index % 32)); - } + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); void InitAsDefaultInstance(); static EnumDescriptorProto* default_instance_; @@ -1093,6 +1091,7 @@ class LIBPROTOBUF_EXPORT EnumValueDescriptorProto : public ::google::protobuf::M inline void set_name(const char* value); inline void set_name(const char* value, size_t size); inline ::std::string* mutable_name(); + inline ::std::string* release_name(); // optional int32 number = 2; inline bool has_number() const; @@ -1107,32 +1106,29 @@ class LIBPROTOBUF_EXPORT EnumValueDescriptorProto : public ::google::protobuf::M static const int kOptionsFieldNumber = 3; inline const ::google::protobuf::EnumValueOptions& options() const; inline ::google::protobuf::EnumValueOptions* mutable_options(); + inline ::google::protobuf::EnumValueOptions* release_options(); // @@protoc_insertion_point(class_scope:google.protobuf.EnumValueDescriptorProto) private: + inline void set_has_name(); + inline void clear_has_name(); + inline void set_has_number(); + inline void clear_has_number(); + inline void set_has_options(); + inline void clear_has_options(); + ::google::protobuf::UnknownFieldSet _unknown_fields_; - mutable int _cached_size_; ::std::string* name_; - static const ::std::string _default_name_; - ::google::protobuf::int32 number_; ::google::protobuf::EnumValueOptions* options_; - friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + ::google::protobuf::int32 number_; + mutable int _cached_size_; ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32]; - // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? - inline bool _has_bit(int index) const { - return (_has_bits_[index / 32] & (1u << (index % 32))) != 0; - } - inline void _set_bit(int index) { - _has_bits_[index / 32] |= (1u << (index % 32)); - } - inline void _clear_bit(int index) { - _has_bits_[index / 32] &= ~(1u << (index % 32)); - } + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); void InitAsDefaultInstance(); static EnumValueDescriptorProto* default_instance_; @@ -1202,6 +1198,7 @@ class LIBPROTOBUF_EXPORT ServiceDescriptorProto : public ::google::protobuf::Mes inline void set_name(const char* value); inline void set_name(const char* value, size_t size); inline ::std::string* mutable_name(); + inline ::std::string* release_name(); // repeated .google.protobuf.MethodDescriptorProto method = 2; inline int method_size() const; @@ -1221,32 +1218,27 @@ class LIBPROTOBUF_EXPORT ServiceDescriptorProto : public ::google::protobuf::Mes static const int kOptionsFieldNumber = 3; inline const ::google::protobuf::ServiceOptions& options() const; inline ::google::protobuf::ServiceOptions* mutable_options(); + inline ::google::protobuf::ServiceOptions* release_options(); // @@protoc_insertion_point(class_scope:google.protobuf.ServiceDescriptorProto) private: + inline void set_has_name(); + inline void clear_has_name(); + inline void set_has_options(); + inline void clear_has_options(); + ::google::protobuf::UnknownFieldSet _unknown_fields_; - mutable int _cached_size_; ::std::string* name_; - static const ::std::string _default_name_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto > method_; ::google::protobuf::ServiceOptions* options_; - friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + mutable int _cached_size_; ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32]; - // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? - inline bool _has_bit(int index) const { - return (_has_bits_[index / 32] & (1u << (index % 32))) != 0; - } - inline void _set_bit(int index) { - _has_bits_[index / 32] |= (1u << (index % 32)); - } - inline void _clear_bit(int index) { - _has_bits_[index / 32] &= ~(1u << (index % 32)); - } + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); void InitAsDefaultInstance(); static ServiceDescriptorProto* default_instance_; @@ -1316,6 +1308,7 @@ class LIBPROTOBUF_EXPORT MethodDescriptorProto : public ::google::protobuf::Mess inline void set_name(const char* value); inline void set_name(const char* value, size_t size); inline ::std::string* mutable_name(); + inline ::std::string* release_name(); // optional string input_type = 2; inline bool has_input_type() const; @@ -1326,6 +1319,7 @@ class LIBPROTOBUF_EXPORT MethodDescriptorProto : public ::google::protobuf::Mess inline void set_input_type(const char* value); inline void set_input_type(const char* value, size_t size); inline ::std::string* mutable_input_type(); + inline ::std::string* release_input_type(); // optional string output_type = 3; inline bool has_output_type() const; @@ -1336,6 +1330,7 @@ class LIBPROTOBUF_EXPORT MethodDescriptorProto : public ::google::protobuf::Mess inline void set_output_type(const char* value); inline void set_output_type(const char* value, size_t size); inline ::std::string* mutable_output_type(); + inline ::std::string* release_output_type(); // optional .google.protobuf.MethodOptions options = 4; inline bool has_options() const; @@ -1343,35 +1338,32 @@ class LIBPROTOBUF_EXPORT MethodDescriptorProto : public ::google::protobuf::Mess static const int kOptionsFieldNumber = 4; inline const ::google::protobuf::MethodOptions& options() const; inline ::google::protobuf::MethodOptions* mutable_options(); + inline ::google::protobuf::MethodOptions* release_options(); // @@protoc_insertion_point(class_scope:google.protobuf.MethodDescriptorProto) private: + inline void set_has_name(); + inline void clear_has_name(); + inline void set_has_input_type(); + inline void clear_has_input_type(); + inline void set_has_output_type(); + inline void clear_has_output_type(); + inline void set_has_options(); + inline void clear_has_options(); + ::google::protobuf::UnknownFieldSet _unknown_fields_; - mutable int _cached_size_; ::std::string* name_; - static const ::std::string _default_name_; ::std::string* input_type_; - static const ::std::string _default_input_type_; ::std::string* output_type_; - static const ::std::string _default_output_type_; ::google::protobuf::MethodOptions* options_; - friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + mutable int _cached_size_; ::google::protobuf::uint32 _has_bits_[(4 + 31) / 32]; - // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? - inline bool _has_bit(int index) const { - return (_has_bits_[index / 32] & (1u << (index % 32))) != 0; - } - inline void _set_bit(int index) { - _has_bits_[index / 32] |= (1u << (index % 32)); - } - inline void _clear_bit(int index) { - _has_bits_[index / 32] &= ~(1u << (index % 32)); - } + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); void InitAsDefaultInstance(); static MethodDescriptorProto* default_instance_; @@ -1466,6 +1458,7 @@ class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message { inline void set_java_package(const char* value); inline void set_java_package(const char* value, size_t size); inline ::std::string* mutable_java_package(); + inline ::std::string* release_java_package(); // optional string java_outer_classname = 8; inline bool has_java_outer_classname() const; @@ -1476,6 +1469,7 @@ class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message { inline void set_java_outer_classname(const char* value); inline void set_java_outer_classname(const char* value, size_t size); inline ::std::string* mutable_java_outer_classname(); + inline ::std::string* release_java_outer_classname(); // optional bool java_multiple_files = 10 [default = false]; inline bool has_java_multiple_files() const; @@ -1491,6 +1485,13 @@ class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message { inline bool retain_unknown_fields() const; inline void set_retain_unknown_fields(bool value); + // optional bool java_generate_equals_and_hash = 20 [default = false]; + inline bool has_java_generate_equals_and_hash() const; + inline void clear_java_generate_equals_and_hash(); + static const int kJavaGenerateEqualsAndHashFieldNumber = 20; + inline bool java_generate_equals_and_hash() const; + inline void set_java_generate_equals_and_hash(bool value); + // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED]; inline bool has_optimize_for() const; inline void clear_optimize_for(); @@ -1498,21 +1499,21 @@ class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message { inline ::google::protobuf::FileOptions_OptimizeMode optimize_for() const; inline void set_optimize_for(::google::protobuf::FileOptions_OptimizeMode value); - // optional bool cc_generic_services = 16 [default = true]; + // optional bool cc_generic_services = 16 [default = false]; inline bool has_cc_generic_services() const; inline void clear_cc_generic_services(); static const int kCcGenericServicesFieldNumber = 16; inline bool cc_generic_services() const; inline void set_cc_generic_services(bool value); - // optional bool java_generic_services = 17 [default = true]; + // optional bool java_generic_services = 17 [default = false]; inline bool has_java_generic_services() const; inline void clear_java_generic_services(); static const int kJavaGenericServicesFieldNumber = 17; inline bool java_generic_services() const; inline void set_java_generic_services(bool value); - // optional bool py_generic_services = 18 [default = true]; + // optional bool py_generic_services = 18 [default = false]; inline bool has_py_generic_services() const; inline void clear_py_generic_services(); static const int kPyGenericServicesFieldNumber = 18; @@ -1534,38 +1535,47 @@ class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message { GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(FileOptions) // @@protoc_insertion_point(class_scope:google.protobuf.FileOptions) private: + inline void set_has_java_package(); + inline void clear_has_java_package(); + inline void set_has_java_outer_classname(); + inline void clear_has_java_outer_classname(); + inline void set_has_java_multiple_files(); + inline void clear_has_java_multiple_files(); + inline void set_has_retain_unknown_fields(); + inline void clear_has_retain_unknown_fields(); + inline void set_has_java_generate_equals_and_hash(); + inline void clear_has_java_generate_equals_and_hash(); + inline void set_has_optimize_for(); + inline void clear_has_optimize_for(); + inline void set_has_cc_generic_services(); + inline void clear_has_cc_generic_services(); + inline void set_has_java_generic_services(); + inline void clear_has_java_generic_services(); + inline void set_has_py_generic_services(); + inline void clear_has_py_generic_services(); + ::google::protobuf::internal::ExtensionSet _extensions_; + ::google::protobuf::UnknownFieldSet _unknown_fields_; - mutable int _cached_size_; ::std::string* java_package_; - static const ::std::string _default_java_package_; ::std::string* java_outer_classname_; - static const ::std::string _default_java_outer_classname_; bool java_multiple_files_; bool retain_unknown_fields_; - int optimize_for_; + bool java_generate_equals_and_hash_; bool cc_generic_services_; + int optimize_for_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_; bool java_generic_services_; bool py_generic_services_; - ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(10 + 31) / 32]; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); - ::google::protobuf::uint32 _has_bits_[(9 + 31) / 32]; - - // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? - inline bool _has_bit(int index) const { - return (_has_bits_[index / 32] & (1u << (index % 32))) != 0; - } - inline void _set_bit(int index) { - _has_bits_[index / 32] |= (1u << (index % 32)); - } - inline void _clear_bit(int index) { - _has_bits_[index / 32] &= ~(1u << (index % 32)); - } - void InitAsDefaultInstance(); static FileOptions* default_instance_; }; @@ -1654,29 +1664,25 @@ class LIBPROTOBUF_EXPORT MessageOptions : public ::google::protobuf::Message { GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(MessageOptions) // @@protoc_insertion_point(class_scope:google.protobuf.MessageOptions) private: + inline void set_has_message_set_wire_format(); + inline void clear_has_message_set_wire_format(); + inline void set_has_no_standard_descriptor_accessor(); + inline void clear_has_no_standard_descriptor_accessor(); + ::google::protobuf::internal::ExtensionSet _extensions_; + ::google::protobuf::UnknownFieldSet _unknown_fields_; - mutable int _cached_size_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_; bool message_set_wire_format_; bool no_standard_descriptor_accessor_; - ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_; - friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + mutable int _cached_size_; ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32]; - // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? - inline bool _has_bit(int index) const { - return (_has_bits_[index / 32] & (1u << (index % 32))) != 0; - } - inline void _set_bit(int index) { - _has_bits_[index / 32] |= (1u << (index % 32)); - } - inline void _clear_bit(int index) { - _has_bits_[index / 32] &= ~(1u << (index % 32)); - } + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); void InitAsDefaultInstance(); static MessageOptions* default_instance_; @@ -1792,6 +1798,7 @@ class LIBPROTOBUF_EXPORT FieldOptions : public ::google::protobuf::Message { inline void set_experimental_map_key(const char* value); inline void set_experimental_map_key(const char* value, size_t size); inline ::std::string* mutable_experimental_map_key(); + inline ::std::string* release_experimental_map_key(); // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; inline int uninterpreted_option_size() const; @@ -1808,32 +1815,31 @@ class LIBPROTOBUF_EXPORT FieldOptions : public ::google::protobuf::Message { GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(FieldOptions) // @@protoc_insertion_point(class_scope:google.protobuf.FieldOptions) private: + inline void set_has_ctype(); + inline void clear_has_ctype(); + inline void set_has_packed(); + inline void clear_has_packed(); + inline void set_has_deprecated(); + inline void clear_has_deprecated(); + inline void set_has_experimental_map_key(); + inline void clear_has_experimental_map_key(); + ::google::protobuf::internal::ExtensionSet _extensions_; + ::google::protobuf::UnknownFieldSet _unknown_fields_; - mutable int _cached_size_; int ctype_; bool packed_; bool deprecated_; ::std::string* experimental_map_key_; - static const ::std::string _default_experimental_map_key_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_; - friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + mutable int _cached_size_; ::google::protobuf::uint32 _has_bits_[(5 + 31) / 32]; - // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? - inline bool _has_bit(int index) const { - return (_has_bits_[index / 32] & (1u << (index % 32))) != 0; - } - inline void _set_bit(int index) { - _has_bits_[index / 32] |= (1u << (index % 32)); - } - inline void _clear_bit(int index) { - _has_bits_[index / 32] &= ~(1u << (index % 32)); - } + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); void InitAsDefaultInstance(); static FieldOptions* default_instance_; @@ -1909,27 +1915,19 @@ class LIBPROTOBUF_EXPORT EnumOptions : public ::google::protobuf::Message { GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(EnumOptions) // @@protoc_insertion_point(class_scope:google.protobuf.EnumOptions) private: + ::google::protobuf::internal::ExtensionSet _extensions_; + ::google::protobuf::UnknownFieldSet _unknown_fields_; - mutable int _cached_size_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_; - friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + mutable int _cached_size_; ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; - // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? - inline bool _has_bit(int index) const { - return (_has_bits_[index / 32] & (1u << (index % 32))) != 0; - } - inline void _set_bit(int index) { - _has_bits_[index / 32] |= (1u << (index % 32)); - } - inline void _clear_bit(int index) { - _has_bits_[index / 32] &= ~(1u << (index % 32)); - } + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); void InitAsDefaultInstance(); static EnumOptions* default_instance_; @@ -2005,27 +2003,19 @@ class LIBPROTOBUF_EXPORT EnumValueOptions : public ::google::protobuf::Message { GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(EnumValueOptions) // @@protoc_insertion_point(class_scope:google.protobuf.EnumValueOptions) private: + ::google::protobuf::internal::ExtensionSet _extensions_; + ::google::protobuf::UnknownFieldSet _unknown_fields_; - mutable int _cached_size_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_; - friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + mutable int _cached_size_; ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; - // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? - inline bool _has_bit(int index) const { - return (_has_bits_[index / 32] & (1u << (index % 32))) != 0; - } - inline void _set_bit(int index) { - _has_bits_[index / 32] |= (1u << (index % 32)); - } - inline void _clear_bit(int index) { - _has_bits_[index / 32] &= ~(1u << (index % 32)); - } + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); void InitAsDefaultInstance(); static EnumValueOptions* default_instance_; @@ -2101,27 +2091,19 @@ class LIBPROTOBUF_EXPORT ServiceOptions : public ::google::protobuf::Message { GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(ServiceOptions) // @@protoc_insertion_point(class_scope:google.protobuf.ServiceOptions) private: + ::google::protobuf::internal::ExtensionSet _extensions_; + ::google::protobuf::UnknownFieldSet _unknown_fields_; - mutable int _cached_size_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_; - friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + mutable int _cached_size_; ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; - // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? - inline bool _has_bit(int index) const { - return (_has_bits_[index / 32] & (1u << (index % 32))) != 0; - } - inline void _set_bit(int index) { - _has_bits_[index / 32] |= (1u << (index % 32)); - } - inline void _clear_bit(int index) { - _has_bits_[index / 32] &= ~(1u << (index % 32)); - } + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); void InitAsDefaultInstance(); static ServiceOptions* default_instance_; @@ -2197,27 +2179,19 @@ class LIBPROTOBUF_EXPORT MethodOptions : public ::google::protobuf::Message { GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(MethodOptions) // @@protoc_insertion_point(class_scope:google.protobuf.MethodOptions) private: + ::google::protobuf::internal::ExtensionSet _extensions_; + ::google::protobuf::UnknownFieldSet _unknown_fields_; - mutable int _cached_size_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_; - friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + mutable int _cached_size_; ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; - // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? - inline bool _has_bit(int index) const { - return (_has_bits_[index / 32] & (1u << (index % 32))) != 0; - } - inline void _set_bit(int index) { - _has_bits_[index / 32] |= (1u << (index % 32)); - } - inline void _clear_bit(int index) { - _has_bits_[index / 32] &= ~(1u << (index % 32)); - } + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); void InitAsDefaultInstance(); static MethodOptions* default_instance_; @@ -2287,6 +2261,7 @@ class LIBPROTOBUF_EXPORT UninterpretedOption_NamePart : public ::google::protobu inline void set_name_part(const char* value); inline void set_name_part(const char* value, size_t size); inline ::std::string* mutable_name_part(); + inline ::std::string* release_name_part(); // required bool is_extension = 2; inline bool has_is_extension() const; @@ -2297,28 +2272,22 @@ class LIBPROTOBUF_EXPORT UninterpretedOption_NamePart : public ::google::protobu // @@protoc_insertion_point(class_scope:google.protobuf.UninterpretedOption.NamePart) private: + inline void set_has_name_part(); + inline void clear_has_name_part(); + inline void set_has_is_extension(); + inline void clear_has_is_extension(); + ::google::protobuf::UnknownFieldSet _unknown_fields_; - mutable int _cached_size_; ::std::string* name_part_; - static const ::std::string _default_name_part_; bool is_extension_; - friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); - friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + mutable int _cached_size_; ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; - // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? - inline bool _has_bit(int index) const { - return (_has_bits_[index / 32] & (1u << (index % 32))) != 0; - } - inline void _set_bit(int index) { - _has_bits_[index / 32] |= (1u << (index % 32)); - } - inline void _clear_bit(int index) { - _has_bits_[index / 32] &= ~(1u << (index % 32)); - } + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); void InitAsDefaultInstance(); static UninterpretedOption_NamePart* default_instance_; @@ -2402,6 +2371,7 @@ class LIBPROTOBUF_EXPORT UninterpretedOption : public ::google::protobuf::Messag inline void set_identifier_value(const char* value); inline void set_identifier_value(const char* value, size_t size); inline ::std::string* mutable_identifier_value(); + inline ::std::string* release_identifier_value(); // optional uint64 positive_int_value = 4; inline bool has_positive_int_value() const; @@ -2433,39 +2403,240 @@ class LIBPROTOBUF_EXPORT UninterpretedOption : public ::google::protobuf::Messag inline void set_string_value(const char* value); inline void set_string_value(const void* value, size_t size); inline ::std::string* mutable_string_value(); + inline ::std::string* release_string_value(); + + // optional string aggregate_value = 8; + inline bool has_aggregate_value() const; + inline void clear_aggregate_value(); + static const int kAggregateValueFieldNumber = 8; + inline const ::std::string& aggregate_value() const; + inline void set_aggregate_value(const ::std::string& value); + inline void set_aggregate_value(const char* value); + inline void set_aggregate_value(const char* value, size_t size); + inline ::std::string* mutable_aggregate_value(); + inline ::std::string* release_aggregate_value(); // @@protoc_insertion_point(class_scope:google.protobuf.UninterpretedOption) private: + inline void set_has_identifier_value(); + inline void clear_has_identifier_value(); + inline void set_has_positive_int_value(); + inline void clear_has_positive_int_value(); + inline void set_has_negative_int_value(); + inline void clear_has_negative_int_value(); + inline void set_has_double_value(); + inline void clear_has_double_value(); + inline void set_has_string_value(); + inline void clear_has_string_value(); + inline void set_has_aggregate_value(); + inline void clear_has_aggregate_value(); + ::google::protobuf::UnknownFieldSet _unknown_fields_; - mutable int _cached_size_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart > name_; ::std::string* identifier_value_; - static const ::std::string _default_identifier_value_; ::google::protobuf::uint64 positive_int_value_; ::google::protobuf::int64 negative_int_value_; double double_value_; ::std::string* string_value_; - static const ::std::string _default_string_value_; + ::std::string* aggregate_value_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(7 + 31) / 32]; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); - ::google::protobuf::uint32 _has_bits_[(6 + 31) / 32]; + void InitAsDefaultInstance(); + static UninterpretedOption* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT SourceCodeInfo_Location : public ::google::protobuf::Message { + public: + SourceCodeInfo_Location(); + virtual ~SourceCodeInfo_Location(); - // WHY DOES & HAVE LOWER PRECEDENCE THAN != !? - inline bool _has_bit(int index) const { - return (_has_bits_[index / 32] & (1u << (index % 32))) != 0; + SourceCodeInfo_Location(const SourceCodeInfo_Location& from); + + inline SourceCodeInfo_Location& operator=(const SourceCodeInfo_Location& from) { + CopyFrom(from); + return *this; } - inline void _set_bit(int index) { - _has_bits_[index / 32] |= (1u << (index % 32)); + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; } - inline void _clear_bit(int index) { - _has_bits_[index / 32] &= ~(1u << (index % 32)); + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; } + static const ::google::protobuf::Descriptor* descriptor(); + static const SourceCodeInfo_Location& default_instance(); + + void Swap(SourceCodeInfo_Location* other); + + // implements Message ---------------------------------------------- + + SourceCodeInfo_Location* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const SourceCodeInfo_Location& from); + void MergeFrom(const SourceCodeInfo_Location& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // repeated int32 path = 1 [packed = true]; + inline int path_size() const; + inline void clear_path(); + static const int kPathFieldNumber = 1; + inline ::google::protobuf::int32 path(int index) const; + inline void set_path(int index, ::google::protobuf::int32 value); + inline void add_path(::google::protobuf::int32 value); + inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >& + path() const; + inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >* + mutable_path(); + + // repeated int32 span = 2 [packed = true]; + inline int span_size() const; + inline void clear_span(); + static const int kSpanFieldNumber = 2; + inline ::google::protobuf::int32 span(int index) const; + inline void set_span(int index, ::google::protobuf::int32 value); + inline void add_span(::google::protobuf::int32 value); + inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >& + span() const; + inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >* + mutable_span(); + + // @@protoc_insertion_point(class_scope:google.protobuf.SourceCodeInfo.Location) + private: + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::RepeatedField< ::google::protobuf::int32 > path_; + mutable int _path_cached_byte_size_; + ::google::protobuf::RepeatedField< ::google::protobuf::int32 > span_; + mutable int _span_cached_byte_size_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; + + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + void InitAsDefaultInstance(); - static UninterpretedOption* default_instance_; + static SourceCodeInfo_Location* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT SourceCodeInfo : public ::google::protobuf::Message { + public: + SourceCodeInfo(); + virtual ~SourceCodeInfo(); + + SourceCodeInfo(const SourceCodeInfo& from); + + inline SourceCodeInfo& operator=(const SourceCodeInfo& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _unknown_fields_; + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const SourceCodeInfo& default_instance(); + + void Swap(SourceCodeInfo* other); + + // implements Message ---------------------------------------------- + + SourceCodeInfo* New() const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const SourceCodeInfo& from); + void MergeFrom(const SourceCodeInfo& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + typedef SourceCodeInfo_Location Location; + + // accessors ------------------------------------------------------- + + // repeated .google.protobuf.SourceCodeInfo.Location location = 1; + inline int location_size() const; + inline void clear_location(); + static const int kLocationFieldNumber = 1; + inline const ::google::protobuf::SourceCodeInfo_Location& location(int index) const; + inline ::google::protobuf::SourceCodeInfo_Location* mutable_location(int index); + inline ::google::protobuf::SourceCodeInfo_Location* add_location(); + inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location >& + location() const; + inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location >* + mutable_location(); + + // @@protoc_insertion_point(class_scope:google.protobuf.SourceCodeInfo) + private: + + ::google::protobuf::UnknownFieldSet _unknown_fields_; + + ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location > location_; + + mutable int _cached_size_; + ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; + + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + + void InitAsDefaultInstance(); + static SourceCodeInfo* default_instance_; }; // =================================================================== @@ -2505,87 +2676,119 @@ FileDescriptorSet::mutable_file() { // optional string name = 1; inline bool FileDescriptorProto::has_name() const { - return _has_bit(0); + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void FileDescriptorProto::set_has_name() { + _has_bits_[0] |= 0x00000001u; +} +inline void FileDescriptorProto::clear_has_name() { + _has_bits_[0] &= ~0x00000001u; } inline void FileDescriptorProto::clear_name() { - if (name_ != &_default_name_) { + if (name_ != &::google::protobuf::internal::kEmptyString) { name_->clear(); } - _clear_bit(0); + clear_has_name(); } inline const ::std::string& FileDescriptorProto::name() const { return *name_; } inline void FileDescriptorProto::set_name(const ::std::string& value) { - _set_bit(0); - if (name_ == &_default_name_) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { name_ = new ::std::string; } name_->assign(value); } inline void FileDescriptorProto::set_name(const char* value) { - _set_bit(0); - if (name_ == &_default_name_) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { name_ = new ::std::string; } name_->assign(value); } inline void FileDescriptorProto::set_name(const char* value, size_t size) { - _set_bit(0); - if (name_ == &_default_name_) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { name_ = new ::std::string; } name_->assign(reinterpret_cast<const char*>(value), size); } inline ::std::string* FileDescriptorProto::mutable_name() { - _set_bit(0); - if (name_ == &_default_name_) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { name_ = new ::std::string; } return name_; } +inline ::std::string* FileDescriptorProto::release_name() { + clear_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = name_; + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} // optional string package = 2; inline bool FileDescriptorProto::has_package() const { - return _has_bit(1); + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void FileDescriptorProto::set_has_package() { + _has_bits_[0] |= 0x00000002u; +} +inline void FileDescriptorProto::clear_has_package() { + _has_bits_[0] &= ~0x00000002u; } inline void FileDescriptorProto::clear_package() { - if (package_ != &_default_package_) { + if (package_ != &::google::protobuf::internal::kEmptyString) { package_->clear(); } - _clear_bit(1); + clear_has_package(); } inline const ::std::string& FileDescriptorProto::package() const { return *package_; } inline void FileDescriptorProto::set_package(const ::std::string& value) { - _set_bit(1); - if (package_ == &_default_package_) { + set_has_package(); + if (package_ == &::google::protobuf::internal::kEmptyString) { package_ = new ::std::string; } package_->assign(value); } inline void FileDescriptorProto::set_package(const char* value) { - _set_bit(1); - if (package_ == &_default_package_) { + set_has_package(); + if (package_ == &::google::protobuf::internal::kEmptyString) { package_ = new ::std::string; } package_->assign(value); } inline void FileDescriptorProto::set_package(const char* value, size_t size) { - _set_bit(1); - if (package_ == &_default_package_) { + set_has_package(); + if (package_ == &::google::protobuf::internal::kEmptyString) { package_ = new ::std::string; } package_->assign(reinterpret_cast<const char*>(value), size); } inline ::std::string* FileDescriptorProto::mutable_package() { - _set_bit(1); - if (package_ == &_default_package_) { + set_has_package(); + if (package_ == &::google::protobuf::internal::kEmptyString) { package_ = new ::std::string; } return package_; } +inline ::std::string* FileDescriptorProto::release_package() { + clear_has_package(); + if (package_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = package_; + package_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} // repeated string dependency = 3; inline int FileDescriptorProto::dependency_size() const { @@ -2733,20 +2936,61 @@ FileDescriptorProto::mutable_extension() { // optional .google.protobuf.FileOptions options = 8; inline bool FileDescriptorProto::has_options() const { - return _has_bit(7); + return (_has_bits_[0] & 0x00000080u) != 0; +} +inline void FileDescriptorProto::set_has_options() { + _has_bits_[0] |= 0x00000080u; +} +inline void FileDescriptorProto::clear_has_options() { + _has_bits_[0] &= ~0x00000080u; } inline void FileDescriptorProto::clear_options() { if (options_ != NULL) options_->::google::protobuf::FileOptions::Clear(); - _clear_bit(7); + clear_has_options(); } inline const ::google::protobuf::FileOptions& FileDescriptorProto::options() const { return options_ != NULL ? *options_ : *default_instance_->options_; } inline ::google::protobuf::FileOptions* FileDescriptorProto::mutable_options() { - _set_bit(7); + set_has_options(); if (options_ == NULL) options_ = new ::google::protobuf::FileOptions; return options_; } +inline ::google::protobuf::FileOptions* FileDescriptorProto::release_options() { + clear_has_options(); + ::google::protobuf::FileOptions* temp = options_; + options_ = NULL; + return temp; +} + +// optional .google.protobuf.SourceCodeInfo source_code_info = 9; +inline bool FileDescriptorProto::has_source_code_info() const { + return (_has_bits_[0] & 0x00000100u) != 0; +} +inline void FileDescriptorProto::set_has_source_code_info() { + _has_bits_[0] |= 0x00000100u; +} +inline void FileDescriptorProto::clear_has_source_code_info() { + _has_bits_[0] &= ~0x00000100u; +} +inline void FileDescriptorProto::clear_source_code_info() { + if (source_code_info_ != NULL) source_code_info_->::google::protobuf::SourceCodeInfo::Clear(); + clear_has_source_code_info(); +} +inline const ::google::protobuf::SourceCodeInfo& FileDescriptorProto::source_code_info() const { + return source_code_info_ != NULL ? *source_code_info_ : *default_instance_->source_code_info_; +} +inline ::google::protobuf::SourceCodeInfo* FileDescriptorProto::mutable_source_code_info() { + set_has_source_code_info(); + if (source_code_info_ == NULL) source_code_info_ = new ::google::protobuf::SourceCodeInfo; + return source_code_info_; +} +inline ::google::protobuf::SourceCodeInfo* FileDescriptorProto::release_source_code_info() { + clear_has_source_code_info(); + ::google::protobuf::SourceCodeInfo* temp = source_code_info_; + source_code_info_ = NULL; + return temp; +} // ------------------------------------------------------------------- @@ -2754,33 +2998,45 @@ inline ::google::protobuf::FileOptions* FileDescriptorProto::mutable_options() { // optional int32 start = 1; inline bool DescriptorProto_ExtensionRange::has_start() const { - return _has_bit(0); + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void DescriptorProto_ExtensionRange::set_has_start() { + _has_bits_[0] |= 0x00000001u; +} +inline void DescriptorProto_ExtensionRange::clear_has_start() { + _has_bits_[0] &= ~0x00000001u; } inline void DescriptorProto_ExtensionRange::clear_start() { start_ = 0; - _clear_bit(0); + clear_has_start(); } inline ::google::protobuf::int32 DescriptorProto_ExtensionRange::start() const { return start_; } inline void DescriptorProto_ExtensionRange::set_start(::google::protobuf::int32 value) { - _set_bit(0); + set_has_start(); start_ = value; } // optional int32 end = 2; inline bool DescriptorProto_ExtensionRange::has_end() const { - return _has_bit(1); + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void DescriptorProto_ExtensionRange::set_has_end() { + _has_bits_[0] |= 0x00000002u; +} +inline void DescriptorProto_ExtensionRange::clear_has_end() { + _has_bits_[0] &= ~0x00000002u; } inline void DescriptorProto_ExtensionRange::clear_end() { end_ = 0; - _clear_bit(1); + clear_has_end(); } inline ::google::protobuf::int32 DescriptorProto_ExtensionRange::end() const { return end_; } inline void DescriptorProto_ExtensionRange::set_end(::google::protobuf::int32 value) { - _set_bit(1); + set_has_end(); end_ = value; } @@ -2790,45 +3046,61 @@ inline void DescriptorProto_ExtensionRange::set_end(::google::protobuf::int32 va // optional string name = 1; inline bool DescriptorProto::has_name() const { - return _has_bit(0); + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void DescriptorProto::set_has_name() { + _has_bits_[0] |= 0x00000001u; +} +inline void DescriptorProto::clear_has_name() { + _has_bits_[0] &= ~0x00000001u; } inline void DescriptorProto::clear_name() { - if (name_ != &_default_name_) { + if (name_ != &::google::protobuf::internal::kEmptyString) { name_->clear(); } - _clear_bit(0); + clear_has_name(); } inline const ::std::string& DescriptorProto::name() const { return *name_; } inline void DescriptorProto::set_name(const ::std::string& value) { - _set_bit(0); - if (name_ == &_default_name_) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { name_ = new ::std::string; } name_->assign(value); } inline void DescriptorProto::set_name(const char* value) { - _set_bit(0); - if (name_ == &_default_name_) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { name_ = new ::std::string; } name_->assign(value); } inline void DescriptorProto::set_name(const char* value, size_t size) { - _set_bit(0); - if (name_ == &_default_name_) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { name_ = new ::std::string; } name_->assign(reinterpret_cast<const char*>(value), size); } inline ::std::string* DescriptorProto::mutable_name() { - _set_bit(0); - if (name_ == &_default_name_) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { name_ = new ::std::string; } return name_; } +inline ::std::string* DescriptorProto::release_name() { + clear_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = name_; + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} // repeated .google.protobuf.FieldDescriptorProto field = 2; inline int DescriptorProto::field_size() const { @@ -2957,20 +3229,32 @@ DescriptorProto::mutable_extension_range() { // optional .google.protobuf.MessageOptions options = 7; inline bool DescriptorProto::has_options() const { - return _has_bit(6); + return (_has_bits_[0] & 0x00000040u) != 0; +} +inline void DescriptorProto::set_has_options() { + _has_bits_[0] |= 0x00000040u; +} +inline void DescriptorProto::clear_has_options() { + _has_bits_[0] &= ~0x00000040u; } inline void DescriptorProto::clear_options() { if (options_ != NULL) options_->::google::protobuf::MessageOptions::Clear(); - _clear_bit(6); + clear_has_options(); } inline const ::google::protobuf::MessageOptions& DescriptorProto::options() const { return options_ != NULL ? *options_ : *default_instance_->options_; } inline ::google::protobuf::MessageOptions* DescriptorProto::mutable_options() { - _set_bit(6); + set_has_options(); if (options_ == NULL) options_ = new ::google::protobuf::MessageOptions; return options_; } +inline ::google::protobuf::MessageOptions* DescriptorProto::release_options() { + clear_has_options(); + ::google::protobuf::MessageOptions* temp = options_; + options_ = NULL; + return temp; +} // ------------------------------------------------------------------- @@ -2978,238 +3262,332 @@ inline ::google::protobuf::MessageOptions* DescriptorProto::mutable_options() { // optional string name = 1; inline bool FieldDescriptorProto::has_name() const { - return _has_bit(0); + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void FieldDescriptorProto::set_has_name() { + _has_bits_[0] |= 0x00000001u; +} +inline void FieldDescriptorProto::clear_has_name() { + _has_bits_[0] &= ~0x00000001u; } inline void FieldDescriptorProto::clear_name() { - if (name_ != &_default_name_) { + if (name_ != &::google::protobuf::internal::kEmptyString) { name_->clear(); } - _clear_bit(0); + clear_has_name(); } inline const ::std::string& FieldDescriptorProto::name() const { return *name_; } inline void FieldDescriptorProto::set_name(const ::std::string& value) { - _set_bit(0); - if (name_ == &_default_name_) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { name_ = new ::std::string; } name_->assign(value); } inline void FieldDescriptorProto::set_name(const char* value) { - _set_bit(0); - if (name_ == &_default_name_) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { name_ = new ::std::string; } name_->assign(value); } inline void FieldDescriptorProto::set_name(const char* value, size_t size) { - _set_bit(0); - if (name_ == &_default_name_) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { name_ = new ::std::string; } name_->assign(reinterpret_cast<const char*>(value), size); } inline ::std::string* FieldDescriptorProto::mutable_name() { - _set_bit(0); - if (name_ == &_default_name_) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { name_ = new ::std::string; } return name_; } +inline ::std::string* FieldDescriptorProto::release_name() { + clear_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = name_; + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} // optional int32 number = 3; inline bool FieldDescriptorProto::has_number() const { - return _has_bit(1); + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void FieldDescriptorProto::set_has_number() { + _has_bits_[0] |= 0x00000002u; +} +inline void FieldDescriptorProto::clear_has_number() { + _has_bits_[0] &= ~0x00000002u; } inline void FieldDescriptorProto::clear_number() { number_ = 0; - _clear_bit(1); + clear_has_number(); } inline ::google::protobuf::int32 FieldDescriptorProto::number() const { return number_; } inline void FieldDescriptorProto::set_number(::google::protobuf::int32 value) { - _set_bit(1); + set_has_number(); number_ = value; } // optional .google.protobuf.FieldDescriptorProto.Label label = 4; inline bool FieldDescriptorProto::has_label() const { - return _has_bit(2); + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void FieldDescriptorProto::set_has_label() { + _has_bits_[0] |= 0x00000004u; +} +inline void FieldDescriptorProto::clear_has_label() { + _has_bits_[0] &= ~0x00000004u; } inline void FieldDescriptorProto::clear_label() { label_ = 1; - _clear_bit(2); + clear_has_label(); } inline ::google::protobuf::FieldDescriptorProto_Label FieldDescriptorProto::label() const { return static_cast< ::google::protobuf::FieldDescriptorProto_Label >(label_); } inline void FieldDescriptorProto::set_label(::google::protobuf::FieldDescriptorProto_Label value) { GOOGLE_DCHECK(::google::protobuf::FieldDescriptorProto_Label_IsValid(value)); - _set_bit(2); + set_has_label(); label_ = value; } // optional .google.protobuf.FieldDescriptorProto.Type type = 5; inline bool FieldDescriptorProto::has_type() const { - return _has_bit(3); + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void FieldDescriptorProto::set_has_type() { + _has_bits_[0] |= 0x00000008u; +} +inline void FieldDescriptorProto::clear_has_type() { + _has_bits_[0] &= ~0x00000008u; } inline void FieldDescriptorProto::clear_type() { type_ = 1; - _clear_bit(3); + clear_has_type(); } inline ::google::protobuf::FieldDescriptorProto_Type FieldDescriptorProto::type() const { return static_cast< ::google::protobuf::FieldDescriptorProto_Type >(type_); } inline void FieldDescriptorProto::set_type(::google::protobuf::FieldDescriptorProto_Type value) { GOOGLE_DCHECK(::google::protobuf::FieldDescriptorProto_Type_IsValid(value)); - _set_bit(3); + set_has_type(); type_ = value; } // optional string type_name = 6; inline bool FieldDescriptorProto::has_type_name() const { - return _has_bit(4); + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void FieldDescriptorProto::set_has_type_name() { + _has_bits_[0] |= 0x00000010u; +} +inline void FieldDescriptorProto::clear_has_type_name() { + _has_bits_[0] &= ~0x00000010u; } inline void FieldDescriptorProto::clear_type_name() { - if (type_name_ != &_default_type_name_) { + if (type_name_ != &::google::protobuf::internal::kEmptyString) { type_name_->clear(); } - _clear_bit(4); + clear_has_type_name(); } inline const ::std::string& FieldDescriptorProto::type_name() const { return *type_name_; } inline void FieldDescriptorProto::set_type_name(const ::std::string& value) { - _set_bit(4); - if (type_name_ == &_default_type_name_) { + set_has_type_name(); + if (type_name_ == &::google::protobuf::internal::kEmptyString) { type_name_ = new ::std::string; } type_name_->assign(value); } inline void FieldDescriptorProto::set_type_name(const char* value) { - _set_bit(4); - if (type_name_ == &_default_type_name_) { + set_has_type_name(); + if (type_name_ == &::google::protobuf::internal::kEmptyString) { type_name_ = new ::std::string; } type_name_->assign(value); } inline void FieldDescriptorProto::set_type_name(const char* value, size_t size) { - _set_bit(4); - if (type_name_ == &_default_type_name_) { + set_has_type_name(); + if (type_name_ == &::google::protobuf::internal::kEmptyString) { type_name_ = new ::std::string; } type_name_->assign(reinterpret_cast<const char*>(value), size); } inline ::std::string* FieldDescriptorProto::mutable_type_name() { - _set_bit(4); - if (type_name_ == &_default_type_name_) { + set_has_type_name(); + if (type_name_ == &::google::protobuf::internal::kEmptyString) { type_name_ = new ::std::string; } return type_name_; } +inline ::std::string* FieldDescriptorProto::release_type_name() { + clear_has_type_name(); + if (type_name_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = type_name_; + type_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} // optional string extendee = 2; inline bool FieldDescriptorProto::has_extendee() const { - return _has_bit(5); + return (_has_bits_[0] & 0x00000020u) != 0; +} +inline void FieldDescriptorProto::set_has_extendee() { + _has_bits_[0] |= 0x00000020u; +} +inline void FieldDescriptorProto::clear_has_extendee() { + _has_bits_[0] &= ~0x00000020u; } inline void FieldDescriptorProto::clear_extendee() { - if (extendee_ != &_default_extendee_) { + if (extendee_ != &::google::protobuf::internal::kEmptyString) { extendee_->clear(); } - _clear_bit(5); + clear_has_extendee(); } inline const ::std::string& FieldDescriptorProto::extendee() const { return *extendee_; } inline void FieldDescriptorProto::set_extendee(const ::std::string& value) { - _set_bit(5); - if (extendee_ == &_default_extendee_) { + set_has_extendee(); + if (extendee_ == &::google::protobuf::internal::kEmptyString) { extendee_ = new ::std::string; } extendee_->assign(value); } inline void FieldDescriptorProto::set_extendee(const char* value) { - _set_bit(5); - if (extendee_ == &_default_extendee_) { + set_has_extendee(); + if (extendee_ == &::google::protobuf::internal::kEmptyString) { extendee_ = new ::std::string; } extendee_->assign(value); } inline void FieldDescriptorProto::set_extendee(const char* value, size_t size) { - _set_bit(5); - if (extendee_ == &_default_extendee_) { + set_has_extendee(); + if (extendee_ == &::google::protobuf::internal::kEmptyString) { extendee_ = new ::std::string; } extendee_->assign(reinterpret_cast<const char*>(value), size); } inline ::std::string* FieldDescriptorProto::mutable_extendee() { - _set_bit(5); - if (extendee_ == &_default_extendee_) { + set_has_extendee(); + if (extendee_ == &::google::protobuf::internal::kEmptyString) { extendee_ = new ::std::string; } return extendee_; } +inline ::std::string* FieldDescriptorProto::release_extendee() { + clear_has_extendee(); + if (extendee_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = extendee_; + extendee_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} // optional string default_value = 7; inline bool FieldDescriptorProto::has_default_value() const { - return _has_bit(6); + return (_has_bits_[0] & 0x00000040u) != 0; +} +inline void FieldDescriptorProto::set_has_default_value() { + _has_bits_[0] |= 0x00000040u; +} +inline void FieldDescriptorProto::clear_has_default_value() { + _has_bits_[0] &= ~0x00000040u; } inline void FieldDescriptorProto::clear_default_value() { - if (default_value_ != &_default_default_value_) { + if (default_value_ != &::google::protobuf::internal::kEmptyString) { default_value_->clear(); } - _clear_bit(6); + clear_has_default_value(); } inline const ::std::string& FieldDescriptorProto::default_value() const { return *default_value_; } inline void FieldDescriptorProto::set_default_value(const ::std::string& value) { - _set_bit(6); - if (default_value_ == &_default_default_value_) { + set_has_default_value(); + if (default_value_ == &::google::protobuf::internal::kEmptyString) { default_value_ = new ::std::string; } default_value_->assign(value); } inline void FieldDescriptorProto::set_default_value(const char* value) { - _set_bit(6); - if (default_value_ == &_default_default_value_) { + set_has_default_value(); + if (default_value_ == &::google::protobuf::internal::kEmptyString) { default_value_ = new ::std::string; } default_value_->assign(value); } inline void FieldDescriptorProto::set_default_value(const char* value, size_t size) { - _set_bit(6); - if (default_value_ == &_default_default_value_) { + set_has_default_value(); + if (default_value_ == &::google::protobuf::internal::kEmptyString) { default_value_ = new ::std::string; } default_value_->assign(reinterpret_cast<const char*>(value), size); } inline ::std::string* FieldDescriptorProto::mutable_default_value() { - _set_bit(6); - if (default_value_ == &_default_default_value_) { + set_has_default_value(); + if (default_value_ == &::google::protobuf::internal::kEmptyString) { default_value_ = new ::std::string; } return default_value_; } +inline ::std::string* FieldDescriptorProto::release_default_value() { + clear_has_default_value(); + if (default_value_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = default_value_; + default_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} // optional .google.protobuf.FieldOptions options = 8; inline bool FieldDescriptorProto::has_options() const { - return _has_bit(7); + return (_has_bits_[0] & 0x00000080u) != 0; +} +inline void FieldDescriptorProto::set_has_options() { + _has_bits_[0] |= 0x00000080u; +} +inline void FieldDescriptorProto::clear_has_options() { + _has_bits_[0] &= ~0x00000080u; } inline void FieldDescriptorProto::clear_options() { if (options_ != NULL) options_->::google::protobuf::FieldOptions::Clear(); - _clear_bit(7); + clear_has_options(); } inline const ::google::protobuf::FieldOptions& FieldDescriptorProto::options() const { return options_ != NULL ? *options_ : *default_instance_->options_; } inline ::google::protobuf::FieldOptions* FieldDescriptorProto::mutable_options() { - _set_bit(7); + set_has_options(); if (options_ == NULL) options_ = new ::google::protobuf::FieldOptions; return options_; } +inline ::google::protobuf::FieldOptions* FieldDescriptorProto::release_options() { + clear_has_options(); + ::google::protobuf::FieldOptions* temp = options_; + options_ = NULL; + return temp; +} // ------------------------------------------------------------------- @@ -3217,45 +3595,61 @@ inline ::google::protobuf::FieldOptions* FieldDescriptorProto::mutable_options() // optional string name = 1; inline bool EnumDescriptorProto::has_name() const { - return _has_bit(0); + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void EnumDescriptorProto::set_has_name() { + _has_bits_[0] |= 0x00000001u; +} +inline void EnumDescriptorProto::clear_has_name() { + _has_bits_[0] &= ~0x00000001u; } inline void EnumDescriptorProto::clear_name() { - if (name_ != &_default_name_) { + if (name_ != &::google::protobuf::internal::kEmptyString) { name_->clear(); } - _clear_bit(0); + clear_has_name(); } inline const ::std::string& EnumDescriptorProto::name() const { return *name_; } inline void EnumDescriptorProto::set_name(const ::std::string& value) { - _set_bit(0); - if (name_ == &_default_name_) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { name_ = new ::std::string; } name_->assign(value); } inline void EnumDescriptorProto::set_name(const char* value) { - _set_bit(0); - if (name_ == &_default_name_) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { name_ = new ::std::string; } name_->assign(value); } inline void EnumDescriptorProto::set_name(const char* value, size_t size) { - _set_bit(0); - if (name_ == &_default_name_) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { name_ = new ::std::string; } name_->assign(reinterpret_cast<const char*>(value), size); } inline ::std::string* EnumDescriptorProto::mutable_name() { - _set_bit(0); - if (name_ == &_default_name_) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { name_ = new ::std::string; } return name_; } +inline ::std::string* EnumDescriptorProto::release_name() { + clear_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = name_; + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} // repeated .google.protobuf.EnumValueDescriptorProto value = 2; inline int EnumDescriptorProto::value_size() const { @@ -3284,20 +3678,32 @@ EnumDescriptorProto::mutable_value() { // optional .google.protobuf.EnumOptions options = 3; inline bool EnumDescriptorProto::has_options() const { - return _has_bit(2); + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void EnumDescriptorProto::set_has_options() { + _has_bits_[0] |= 0x00000004u; +} +inline void EnumDescriptorProto::clear_has_options() { + _has_bits_[0] &= ~0x00000004u; } inline void EnumDescriptorProto::clear_options() { if (options_ != NULL) options_->::google::protobuf::EnumOptions::Clear(); - _clear_bit(2); + clear_has_options(); } inline const ::google::protobuf::EnumOptions& EnumDescriptorProto::options() const { return options_ != NULL ? *options_ : *default_instance_->options_; } inline ::google::protobuf::EnumOptions* EnumDescriptorProto::mutable_options() { - _set_bit(2); + set_has_options(); if (options_ == NULL) options_ = new ::google::protobuf::EnumOptions; return options_; } +inline ::google::protobuf::EnumOptions* EnumDescriptorProto::release_options() { + clear_has_options(); + ::google::protobuf::EnumOptions* temp = options_; + options_ = NULL; + return temp; +} // ------------------------------------------------------------------- @@ -3305,78 +3711,112 @@ inline ::google::protobuf::EnumOptions* EnumDescriptorProto::mutable_options() { // optional string name = 1; inline bool EnumValueDescriptorProto::has_name() const { - return _has_bit(0); + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void EnumValueDescriptorProto::set_has_name() { + _has_bits_[0] |= 0x00000001u; +} +inline void EnumValueDescriptorProto::clear_has_name() { + _has_bits_[0] &= ~0x00000001u; } inline void EnumValueDescriptorProto::clear_name() { - if (name_ != &_default_name_) { + if (name_ != &::google::protobuf::internal::kEmptyString) { name_->clear(); } - _clear_bit(0); + clear_has_name(); } inline const ::std::string& EnumValueDescriptorProto::name() const { return *name_; } inline void EnumValueDescriptorProto::set_name(const ::std::string& value) { - _set_bit(0); - if (name_ == &_default_name_) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { name_ = new ::std::string; } name_->assign(value); } inline void EnumValueDescriptorProto::set_name(const char* value) { - _set_bit(0); - if (name_ == &_default_name_) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { name_ = new ::std::string; } name_->assign(value); } inline void EnumValueDescriptorProto::set_name(const char* value, size_t size) { - _set_bit(0); - if (name_ == &_default_name_) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { name_ = new ::std::string; } name_->assign(reinterpret_cast<const char*>(value), size); } inline ::std::string* EnumValueDescriptorProto::mutable_name() { - _set_bit(0); - if (name_ == &_default_name_) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { name_ = new ::std::string; } return name_; } +inline ::std::string* EnumValueDescriptorProto::release_name() { + clear_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = name_; + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} // optional int32 number = 2; inline bool EnumValueDescriptorProto::has_number() const { - return _has_bit(1); + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void EnumValueDescriptorProto::set_has_number() { + _has_bits_[0] |= 0x00000002u; +} +inline void EnumValueDescriptorProto::clear_has_number() { + _has_bits_[0] &= ~0x00000002u; } inline void EnumValueDescriptorProto::clear_number() { number_ = 0; - _clear_bit(1); + clear_has_number(); } inline ::google::protobuf::int32 EnumValueDescriptorProto::number() const { return number_; } inline void EnumValueDescriptorProto::set_number(::google::protobuf::int32 value) { - _set_bit(1); + set_has_number(); number_ = value; } // optional .google.protobuf.EnumValueOptions options = 3; inline bool EnumValueDescriptorProto::has_options() const { - return _has_bit(2); + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void EnumValueDescriptorProto::set_has_options() { + _has_bits_[0] |= 0x00000004u; +} +inline void EnumValueDescriptorProto::clear_has_options() { + _has_bits_[0] &= ~0x00000004u; } inline void EnumValueDescriptorProto::clear_options() { if (options_ != NULL) options_->::google::protobuf::EnumValueOptions::Clear(); - _clear_bit(2); + clear_has_options(); } inline const ::google::protobuf::EnumValueOptions& EnumValueDescriptorProto::options() const { return options_ != NULL ? *options_ : *default_instance_->options_; } inline ::google::protobuf::EnumValueOptions* EnumValueDescriptorProto::mutable_options() { - _set_bit(2); + set_has_options(); if (options_ == NULL) options_ = new ::google::protobuf::EnumValueOptions; return options_; } +inline ::google::protobuf::EnumValueOptions* EnumValueDescriptorProto::release_options() { + clear_has_options(); + ::google::protobuf::EnumValueOptions* temp = options_; + options_ = NULL; + return temp; +} // ------------------------------------------------------------------- @@ -3384,45 +3824,61 @@ inline ::google::protobuf::EnumValueOptions* EnumValueDescriptorProto::mutable_o // optional string name = 1; inline bool ServiceDescriptorProto::has_name() const { - return _has_bit(0); + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void ServiceDescriptorProto::set_has_name() { + _has_bits_[0] |= 0x00000001u; +} +inline void ServiceDescriptorProto::clear_has_name() { + _has_bits_[0] &= ~0x00000001u; } inline void ServiceDescriptorProto::clear_name() { - if (name_ != &_default_name_) { + if (name_ != &::google::protobuf::internal::kEmptyString) { name_->clear(); } - _clear_bit(0); + clear_has_name(); } inline const ::std::string& ServiceDescriptorProto::name() const { return *name_; } inline void ServiceDescriptorProto::set_name(const ::std::string& value) { - _set_bit(0); - if (name_ == &_default_name_) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { name_ = new ::std::string; } name_->assign(value); } inline void ServiceDescriptorProto::set_name(const char* value) { - _set_bit(0); - if (name_ == &_default_name_) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { name_ = new ::std::string; } name_->assign(value); } inline void ServiceDescriptorProto::set_name(const char* value, size_t size) { - _set_bit(0); - if (name_ == &_default_name_) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { name_ = new ::std::string; } name_->assign(reinterpret_cast<const char*>(value), size); } inline ::std::string* ServiceDescriptorProto::mutable_name() { - _set_bit(0); - if (name_ == &_default_name_) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { name_ = new ::std::string; } return name_; } +inline ::std::string* ServiceDescriptorProto::release_name() { + clear_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = name_; + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} // repeated .google.protobuf.MethodDescriptorProto method = 2; inline int ServiceDescriptorProto::method_size() const { @@ -3451,20 +3907,32 @@ ServiceDescriptorProto::mutable_method() { // optional .google.protobuf.ServiceOptions options = 3; inline bool ServiceDescriptorProto::has_options() const { - return _has_bit(2); + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void ServiceDescriptorProto::set_has_options() { + _has_bits_[0] |= 0x00000004u; +} +inline void ServiceDescriptorProto::clear_has_options() { + _has_bits_[0] &= ~0x00000004u; } inline void ServiceDescriptorProto::clear_options() { if (options_ != NULL) options_->::google::protobuf::ServiceOptions::Clear(); - _clear_bit(2); + clear_has_options(); } inline const ::google::protobuf::ServiceOptions& ServiceDescriptorProto::options() const { return options_ != NULL ? *options_ : *default_instance_->options_; } inline ::google::protobuf::ServiceOptions* ServiceDescriptorProto::mutable_options() { - _set_bit(2); + set_has_options(); if (options_ == NULL) options_ = new ::google::protobuf::ServiceOptions; return options_; } +inline ::google::protobuf::ServiceOptions* ServiceDescriptorProto::release_options() { + clear_has_options(); + ::google::protobuf::ServiceOptions* temp = options_; + options_ = NULL; + return temp; +} // ------------------------------------------------------------------- @@ -3472,146 +3940,206 @@ inline ::google::protobuf::ServiceOptions* ServiceDescriptorProto::mutable_optio // optional string name = 1; inline bool MethodDescriptorProto::has_name() const { - return _has_bit(0); + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void MethodDescriptorProto::set_has_name() { + _has_bits_[0] |= 0x00000001u; +} +inline void MethodDescriptorProto::clear_has_name() { + _has_bits_[0] &= ~0x00000001u; } inline void MethodDescriptorProto::clear_name() { - if (name_ != &_default_name_) { + if (name_ != &::google::protobuf::internal::kEmptyString) { name_->clear(); } - _clear_bit(0); + clear_has_name(); } inline const ::std::string& MethodDescriptorProto::name() const { return *name_; } inline void MethodDescriptorProto::set_name(const ::std::string& value) { - _set_bit(0); - if (name_ == &_default_name_) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { name_ = new ::std::string; } name_->assign(value); } inline void MethodDescriptorProto::set_name(const char* value) { - _set_bit(0); - if (name_ == &_default_name_) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { name_ = new ::std::string; } name_->assign(value); } inline void MethodDescriptorProto::set_name(const char* value, size_t size) { - _set_bit(0); - if (name_ == &_default_name_) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { name_ = new ::std::string; } name_->assign(reinterpret_cast<const char*>(value), size); } inline ::std::string* MethodDescriptorProto::mutable_name() { - _set_bit(0); - if (name_ == &_default_name_) { + set_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { name_ = new ::std::string; } return name_; } +inline ::std::string* MethodDescriptorProto::release_name() { + clear_has_name(); + if (name_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = name_; + name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} // optional string input_type = 2; inline bool MethodDescriptorProto::has_input_type() const { - return _has_bit(1); + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void MethodDescriptorProto::set_has_input_type() { + _has_bits_[0] |= 0x00000002u; +} +inline void MethodDescriptorProto::clear_has_input_type() { + _has_bits_[0] &= ~0x00000002u; } inline void MethodDescriptorProto::clear_input_type() { - if (input_type_ != &_default_input_type_) { + if (input_type_ != &::google::protobuf::internal::kEmptyString) { input_type_->clear(); } - _clear_bit(1); + clear_has_input_type(); } inline const ::std::string& MethodDescriptorProto::input_type() const { return *input_type_; } inline void MethodDescriptorProto::set_input_type(const ::std::string& value) { - _set_bit(1); - if (input_type_ == &_default_input_type_) { + set_has_input_type(); + if (input_type_ == &::google::protobuf::internal::kEmptyString) { input_type_ = new ::std::string; } input_type_->assign(value); } inline void MethodDescriptorProto::set_input_type(const char* value) { - _set_bit(1); - if (input_type_ == &_default_input_type_) { + set_has_input_type(); + if (input_type_ == &::google::protobuf::internal::kEmptyString) { input_type_ = new ::std::string; } input_type_->assign(value); } inline void MethodDescriptorProto::set_input_type(const char* value, size_t size) { - _set_bit(1); - if (input_type_ == &_default_input_type_) { + set_has_input_type(); + if (input_type_ == &::google::protobuf::internal::kEmptyString) { input_type_ = new ::std::string; } input_type_->assign(reinterpret_cast<const char*>(value), size); } inline ::std::string* MethodDescriptorProto::mutable_input_type() { - _set_bit(1); - if (input_type_ == &_default_input_type_) { + set_has_input_type(); + if (input_type_ == &::google::protobuf::internal::kEmptyString) { input_type_ = new ::std::string; } return input_type_; } +inline ::std::string* MethodDescriptorProto::release_input_type() { + clear_has_input_type(); + if (input_type_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = input_type_; + input_type_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} // optional string output_type = 3; inline bool MethodDescriptorProto::has_output_type() const { - return _has_bit(2); + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void MethodDescriptorProto::set_has_output_type() { + _has_bits_[0] |= 0x00000004u; +} +inline void MethodDescriptorProto::clear_has_output_type() { + _has_bits_[0] &= ~0x00000004u; } inline void MethodDescriptorProto::clear_output_type() { - if (output_type_ != &_default_output_type_) { + if (output_type_ != &::google::protobuf::internal::kEmptyString) { output_type_->clear(); } - _clear_bit(2); + clear_has_output_type(); } inline const ::std::string& MethodDescriptorProto::output_type() const { return *output_type_; } inline void MethodDescriptorProto::set_output_type(const ::std::string& value) { - _set_bit(2); - if (output_type_ == &_default_output_type_) { + set_has_output_type(); + if (output_type_ == &::google::protobuf::internal::kEmptyString) { output_type_ = new ::std::string; } output_type_->assign(value); } inline void MethodDescriptorProto::set_output_type(const char* value) { - _set_bit(2); - if (output_type_ == &_default_output_type_) { + set_has_output_type(); + if (output_type_ == &::google::protobuf::internal::kEmptyString) { output_type_ = new ::std::string; } output_type_->assign(value); } inline void MethodDescriptorProto::set_output_type(const char* value, size_t size) { - _set_bit(2); - if (output_type_ == &_default_output_type_) { + set_has_output_type(); + if (output_type_ == &::google::protobuf::internal::kEmptyString) { output_type_ = new ::std::string; } output_type_->assign(reinterpret_cast<const char*>(value), size); } inline ::std::string* MethodDescriptorProto::mutable_output_type() { - _set_bit(2); - if (output_type_ == &_default_output_type_) { + set_has_output_type(); + if (output_type_ == &::google::protobuf::internal::kEmptyString) { output_type_ = new ::std::string; } return output_type_; } +inline ::std::string* MethodDescriptorProto::release_output_type() { + clear_has_output_type(); + if (output_type_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = output_type_; + output_type_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} // optional .google.protobuf.MethodOptions options = 4; inline bool MethodDescriptorProto::has_options() const { - return _has_bit(3); + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void MethodDescriptorProto::set_has_options() { + _has_bits_[0] |= 0x00000008u; +} +inline void MethodDescriptorProto::clear_has_options() { + _has_bits_[0] &= ~0x00000008u; } inline void MethodDescriptorProto::clear_options() { if (options_ != NULL) options_->::google::protobuf::MethodOptions::Clear(); - _clear_bit(3); + clear_has_options(); } inline const ::google::protobuf::MethodOptions& MethodDescriptorProto::options() const { return options_ != NULL ? *options_ : *default_instance_->options_; } inline ::google::protobuf::MethodOptions* MethodDescriptorProto::mutable_options() { - _set_bit(3); + set_has_options(); if (options_ == NULL) options_ = new ::google::protobuf::MethodOptions; return options_; } +inline ::google::protobuf::MethodOptions* MethodDescriptorProto::release_options() { + clear_has_options(); + ::google::protobuf::MethodOptions* temp = options_; + options_ = NULL; + return temp; +} // ------------------------------------------------------------------- @@ -3619,182 +4147,272 @@ inline ::google::protobuf::MethodOptions* MethodDescriptorProto::mutable_options // optional string java_package = 1; inline bool FileOptions::has_java_package() const { - return _has_bit(0); + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void FileOptions::set_has_java_package() { + _has_bits_[0] |= 0x00000001u; +} +inline void FileOptions::clear_has_java_package() { + _has_bits_[0] &= ~0x00000001u; } inline void FileOptions::clear_java_package() { - if (java_package_ != &_default_java_package_) { + if (java_package_ != &::google::protobuf::internal::kEmptyString) { java_package_->clear(); } - _clear_bit(0); + clear_has_java_package(); } inline const ::std::string& FileOptions::java_package() const { return *java_package_; } inline void FileOptions::set_java_package(const ::std::string& value) { - _set_bit(0); - if (java_package_ == &_default_java_package_) { + set_has_java_package(); + if (java_package_ == &::google::protobuf::internal::kEmptyString) { java_package_ = new ::std::string; } java_package_->assign(value); } inline void FileOptions::set_java_package(const char* value) { - _set_bit(0); - if (java_package_ == &_default_java_package_) { + set_has_java_package(); + if (java_package_ == &::google::protobuf::internal::kEmptyString) { java_package_ = new ::std::string; } java_package_->assign(value); } inline void FileOptions::set_java_package(const char* value, size_t size) { - _set_bit(0); - if (java_package_ == &_default_java_package_) { + set_has_java_package(); + if (java_package_ == &::google::protobuf::internal::kEmptyString) { java_package_ = new ::std::string; } java_package_->assign(reinterpret_cast<const char*>(value), size); } inline ::std::string* FileOptions::mutable_java_package() { - _set_bit(0); - if (java_package_ == &_default_java_package_) { + set_has_java_package(); + if (java_package_ == &::google::protobuf::internal::kEmptyString) { java_package_ = new ::std::string; } return java_package_; } +inline ::std::string* FileOptions::release_java_package() { + clear_has_java_package(); + if (java_package_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = java_package_; + java_package_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} // optional string java_outer_classname = 8; inline bool FileOptions::has_java_outer_classname() const { - return _has_bit(1); + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void FileOptions::set_has_java_outer_classname() { + _has_bits_[0] |= 0x00000002u; +} +inline void FileOptions::clear_has_java_outer_classname() { + _has_bits_[0] &= ~0x00000002u; } inline void FileOptions::clear_java_outer_classname() { - if (java_outer_classname_ != &_default_java_outer_classname_) { + if (java_outer_classname_ != &::google::protobuf::internal::kEmptyString) { java_outer_classname_->clear(); } - _clear_bit(1); + clear_has_java_outer_classname(); } inline const ::std::string& FileOptions::java_outer_classname() const { return *java_outer_classname_; } inline void FileOptions::set_java_outer_classname(const ::std::string& value) { - _set_bit(1); - if (java_outer_classname_ == &_default_java_outer_classname_) { + set_has_java_outer_classname(); + if (java_outer_classname_ == &::google::protobuf::internal::kEmptyString) { java_outer_classname_ = new ::std::string; } java_outer_classname_->assign(value); } inline void FileOptions::set_java_outer_classname(const char* value) { - _set_bit(1); - if (java_outer_classname_ == &_default_java_outer_classname_) { + set_has_java_outer_classname(); + if (java_outer_classname_ == &::google::protobuf::internal::kEmptyString) { java_outer_classname_ = new ::std::string; } java_outer_classname_->assign(value); } inline void FileOptions::set_java_outer_classname(const char* value, size_t size) { - _set_bit(1); - if (java_outer_classname_ == &_default_java_outer_classname_) { + set_has_java_outer_classname(); + if (java_outer_classname_ == &::google::protobuf::internal::kEmptyString) { java_outer_classname_ = new ::std::string; } java_outer_classname_->assign(reinterpret_cast<const char*>(value), size); } inline ::std::string* FileOptions::mutable_java_outer_classname() { - _set_bit(1); - if (java_outer_classname_ == &_default_java_outer_classname_) { + set_has_java_outer_classname(); + if (java_outer_classname_ == &::google::protobuf::internal::kEmptyString) { java_outer_classname_ = new ::std::string; } return java_outer_classname_; } +inline ::std::string* FileOptions::release_java_outer_classname() { + clear_has_java_outer_classname(); + if (java_outer_classname_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = java_outer_classname_; + java_outer_classname_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} // optional bool java_multiple_files = 10 [default = false]; inline bool FileOptions::has_java_multiple_files() const { - return _has_bit(2); + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void FileOptions::set_has_java_multiple_files() { + _has_bits_[0] |= 0x00000004u; +} +inline void FileOptions::clear_has_java_multiple_files() { + _has_bits_[0] &= ~0x00000004u; } inline void FileOptions::clear_java_multiple_files() { java_multiple_files_ = false; - _clear_bit(2); + clear_has_java_multiple_files(); } inline bool FileOptions::java_multiple_files() const { return java_multiple_files_; } inline void FileOptions::set_java_multiple_files(bool value) { - _set_bit(2); + set_has_java_multiple_files(); java_multiple_files_ = value; } // optional bool retain_unknown_fields = 11 [default = false]; inline bool FileOptions::has_retain_unknown_fields() const { - return _has_bit(3); + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void FileOptions::set_has_retain_unknown_fields() { + _has_bits_[0] |= 0x00000008u; +} +inline void FileOptions::clear_has_retain_unknown_fields() { + _has_bits_[0] &= ~0x00000008u; } inline void FileOptions::clear_retain_unknown_fields() { retain_unknown_fields_ = false; - _clear_bit(3); + clear_has_retain_unknown_fields(); } inline bool FileOptions::retain_unknown_fields() const { return retain_unknown_fields_; } inline void FileOptions::set_retain_unknown_fields(bool value) { - _set_bit(3); + set_has_retain_unknown_fields(); retain_unknown_fields_ = value; } +// optional bool java_generate_equals_and_hash = 20 [default = false]; +inline bool FileOptions::has_java_generate_equals_and_hash() const { + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void FileOptions::set_has_java_generate_equals_and_hash() { + _has_bits_[0] |= 0x00000010u; +} +inline void FileOptions::clear_has_java_generate_equals_and_hash() { + _has_bits_[0] &= ~0x00000010u; +} +inline void FileOptions::clear_java_generate_equals_and_hash() { + java_generate_equals_and_hash_ = false; + clear_has_java_generate_equals_and_hash(); +} +inline bool FileOptions::java_generate_equals_and_hash() const { + return java_generate_equals_and_hash_; +} +inline void FileOptions::set_java_generate_equals_and_hash(bool value) { + set_has_java_generate_equals_and_hash(); + java_generate_equals_and_hash_ = value; +} + // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED]; inline bool FileOptions::has_optimize_for() const { - return _has_bit(4); + return (_has_bits_[0] & 0x00000020u) != 0; +} +inline void FileOptions::set_has_optimize_for() { + _has_bits_[0] |= 0x00000020u; +} +inline void FileOptions::clear_has_optimize_for() { + _has_bits_[0] &= ~0x00000020u; } inline void FileOptions::clear_optimize_for() { optimize_for_ = 1; - _clear_bit(4); + clear_has_optimize_for(); } inline ::google::protobuf::FileOptions_OptimizeMode FileOptions::optimize_for() const { return static_cast< ::google::protobuf::FileOptions_OptimizeMode >(optimize_for_); } inline void FileOptions::set_optimize_for(::google::protobuf::FileOptions_OptimizeMode value) { GOOGLE_DCHECK(::google::protobuf::FileOptions_OptimizeMode_IsValid(value)); - _set_bit(4); + set_has_optimize_for(); optimize_for_ = value; } -// optional bool cc_generic_services = 16 [default = true]; +// optional bool cc_generic_services = 16 [default = false]; inline bool FileOptions::has_cc_generic_services() const { - return _has_bit(5); + return (_has_bits_[0] & 0x00000040u) != 0; +} +inline void FileOptions::set_has_cc_generic_services() { + _has_bits_[0] |= 0x00000040u; +} +inline void FileOptions::clear_has_cc_generic_services() { + _has_bits_[0] &= ~0x00000040u; } inline void FileOptions::clear_cc_generic_services() { - cc_generic_services_ = true; - _clear_bit(5); + cc_generic_services_ = false; + clear_has_cc_generic_services(); } inline bool FileOptions::cc_generic_services() const { return cc_generic_services_; } inline void FileOptions::set_cc_generic_services(bool value) { - _set_bit(5); + set_has_cc_generic_services(); cc_generic_services_ = value; } -// optional bool java_generic_services = 17 [default = true]; +// optional bool java_generic_services = 17 [default = false]; inline bool FileOptions::has_java_generic_services() const { - return _has_bit(6); + return (_has_bits_[0] & 0x00000080u) != 0; +} +inline void FileOptions::set_has_java_generic_services() { + _has_bits_[0] |= 0x00000080u; +} +inline void FileOptions::clear_has_java_generic_services() { + _has_bits_[0] &= ~0x00000080u; } inline void FileOptions::clear_java_generic_services() { - java_generic_services_ = true; - _clear_bit(6); + java_generic_services_ = false; + clear_has_java_generic_services(); } inline bool FileOptions::java_generic_services() const { return java_generic_services_; } inline void FileOptions::set_java_generic_services(bool value) { - _set_bit(6); + set_has_java_generic_services(); java_generic_services_ = value; } -// optional bool py_generic_services = 18 [default = true]; +// optional bool py_generic_services = 18 [default = false]; inline bool FileOptions::has_py_generic_services() const { - return _has_bit(7); + return (_has_bits_[0] & 0x00000100u) != 0; +} +inline void FileOptions::set_has_py_generic_services() { + _has_bits_[0] |= 0x00000100u; +} +inline void FileOptions::clear_has_py_generic_services() { + _has_bits_[0] &= ~0x00000100u; } inline void FileOptions::clear_py_generic_services() { - py_generic_services_ = true; - _clear_bit(7); + py_generic_services_ = false; + clear_has_py_generic_services(); } inline bool FileOptions::py_generic_services() const { return py_generic_services_; } inline void FileOptions::set_py_generic_services(bool value) { - _set_bit(7); + set_has_py_generic_services(); py_generic_services_ = value; } @@ -3829,33 +4447,45 @@ FileOptions::mutable_uninterpreted_option() { // optional bool message_set_wire_format = 1 [default = false]; inline bool MessageOptions::has_message_set_wire_format() const { - return _has_bit(0); + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void MessageOptions::set_has_message_set_wire_format() { + _has_bits_[0] |= 0x00000001u; +} +inline void MessageOptions::clear_has_message_set_wire_format() { + _has_bits_[0] &= ~0x00000001u; } inline void MessageOptions::clear_message_set_wire_format() { message_set_wire_format_ = false; - _clear_bit(0); + clear_has_message_set_wire_format(); } inline bool MessageOptions::message_set_wire_format() const { return message_set_wire_format_; } inline void MessageOptions::set_message_set_wire_format(bool value) { - _set_bit(0); + set_has_message_set_wire_format(); message_set_wire_format_ = value; } // optional bool no_standard_descriptor_accessor = 2 [default = false]; inline bool MessageOptions::has_no_standard_descriptor_accessor() const { - return _has_bit(1); + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void MessageOptions::set_has_no_standard_descriptor_accessor() { + _has_bits_[0] |= 0x00000002u; +} +inline void MessageOptions::clear_has_no_standard_descriptor_accessor() { + _has_bits_[0] &= ~0x00000002u; } inline void MessageOptions::clear_no_standard_descriptor_accessor() { no_standard_descriptor_accessor_ = false; - _clear_bit(1); + clear_has_no_standard_descriptor_accessor(); } inline bool MessageOptions::no_standard_descriptor_accessor() const { return no_standard_descriptor_accessor_; } inline void MessageOptions::set_no_standard_descriptor_accessor(bool value) { - _set_bit(1); + set_has_no_standard_descriptor_accessor(); no_standard_descriptor_accessor_ = value; } @@ -3890,94 +4520,128 @@ MessageOptions::mutable_uninterpreted_option() { // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING]; inline bool FieldOptions::has_ctype() const { - return _has_bit(0); + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void FieldOptions::set_has_ctype() { + _has_bits_[0] |= 0x00000001u; +} +inline void FieldOptions::clear_has_ctype() { + _has_bits_[0] &= ~0x00000001u; } inline void FieldOptions::clear_ctype() { ctype_ = 0; - _clear_bit(0); + clear_has_ctype(); } inline ::google::protobuf::FieldOptions_CType FieldOptions::ctype() const { return static_cast< ::google::protobuf::FieldOptions_CType >(ctype_); } inline void FieldOptions::set_ctype(::google::protobuf::FieldOptions_CType value) { GOOGLE_DCHECK(::google::protobuf::FieldOptions_CType_IsValid(value)); - _set_bit(0); + set_has_ctype(); ctype_ = value; } // optional bool packed = 2; inline bool FieldOptions::has_packed() const { - return _has_bit(1); + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void FieldOptions::set_has_packed() { + _has_bits_[0] |= 0x00000002u; +} +inline void FieldOptions::clear_has_packed() { + _has_bits_[0] &= ~0x00000002u; } inline void FieldOptions::clear_packed() { packed_ = false; - _clear_bit(1); + clear_has_packed(); } inline bool FieldOptions::packed() const { return packed_; } inline void FieldOptions::set_packed(bool value) { - _set_bit(1); + set_has_packed(); packed_ = value; } // optional bool deprecated = 3 [default = false]; inline bool FieldOptions::has_deprecated() const { - return _has_bit(2); + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void FieldOptions::set_has_deprecated() { + _has_bits_[0] |= 0x00000004u; +} +inline void FieldOptions::clear_has_deprecated() { + _has_bits_[0] &= ~0x00000004u; } inline void FieldOptions::clear_deprecated() { deprecated_ = false; - _clear_bit(2); + clear_has_deprecated(); } inline bool FieldOptions::deprecated() const { return deprecated_; } inline void FieldOptions::set_deprecated(bool value) { - _set_bit(2); + set_has_deprecated(); deprecated_ = value; } // optional string experimental_map_key = 9; inline bool FieldOptions::has_experimental_map_key() const { - return _has_bit(3); + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void FieldOptions::set_has_experimental_map_key() { + _has_bits_[0] |= 0x00000008u; +} +inline void FieldOptions::clear_has_experimental_map_key() { + _has_bits_[0] &= ~0x00000008u; } inline void FieldOptions::clear_experimental_map_key() { - if (experimental_map_key_ != &_default_experimental_map_key_) { + if (experimental_map_key_ != &::google::protobuf::internal::kEmptyString) { experimental_map_key_->clear(); } - _clear_bit(3); + clear_has_experimental_map_key(); } inline const ::std::string& FieldOptions::experimental_map_key() const { return *experimental_map_key_; } inline void FieldOptions::set_experimental_map_key(const ::std::string& value) { - _set_bit(3); - if (experimental_map_key_ == &_default_experimental_map_key_) { + set_has_experimental_map_key(); + if (experimental_map_key_ == &::google::protobuf::internal::kEmptyString) { experimental_map_key_ = new ::std::string; } experimental_map_key_->assign(value); } inline void FieldOptions::set_experimental_map_key(const char* value) { - _set_bit(3); - if (experimental_map_key_ == &_default_experimental_map_key_) { + set_has_experimental_map_key(); + if (experimental_map_key_ == &::google::protobuf::internal::kEmptyString) { experimental_map_key_ = new ::std::string; } experimental_map_key_->assign(value); } inline void FieldOptions::set_experimental_map_key(const char* value, size_t size) { - _set_bit(3); - if (experimental_map_key_ == &_default_experimental_map_key_) { + set_has_experimental_map_key(); + if (experimental_map_key_ == &::google::protobuf::internal::kEmptyString) { experimental_map_key_ = new ::std::string; } experimental_map_key_->assign(reinterpret_cast<const char*>(value), size); } inline ::std::string* FieldOptions::mutable_experimental_map_key() { - _set_bit(3); - if (experimental_map_key_ == &_default_experimental_map_key_) { + set_has_experimental_map_key(); + if (experimental_map_key_ == &::google::protobuf::internal::kEmptyString) { experimental_map_key_ = new ::std::string; } return experimental_map_key_; } +inline ::std::string* FieldOptions::release_experimental_map_key() { + clear_has_experimental_map_key(); + if (experimental_map_key_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = experimental_map_key_; + experimental_map_key_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; inline int FieldOptions::uninterpreted_option_size() const { @@ -4126,59 +4790,81 @@ MethodOptions::mutable_uninterpreted_option() { // required string name_part = 1; inline bool UninterpretedOption_NamePart::has_name_part() const { - return _has_bit(0); + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void UninterpretedOption_NamePart::set_has_name_part() { + _has_bits_[0] |= 0x00000001u; +} +inline void UninterpretedOption_NamePart::clear_has_name_part() { + _has_bits_[0] &= ~0x00000001u; } inline void UninterpretedOption_NamePart::clear_name_part() { - if (name_part_ != &_default_name_part_) { + if (name_part_ != &::google::protobuf::internal::kEmptyString) { name_part_->clear(); } - _clear_bit(0); + clear_has_name_part(); } inline const ::std::string& UninterpretedOption_NamePart::name_part() const { return *name_part_; } inline void UninterpretedOption_NamePart::set_name_part(const ::std::string& value) { - _set_bit(0); - if (name_part_ == &_default_name_part_) { + set_has_name_part(); + if (name_part_ == &::google::protobuf::internal::kEmptyString) { name_part_ = new ::std::string; } name_part_->assign(value); } inline void UninterpretedOption_NamePart::set_name_part(const char* value) { - _set_bit(0); - if (name_part_ == &_default_name_part_) { + set_has_name_part(); + if (name_part_ == &::google::protobuf::internal::kEmptyString) { name_part_ = new ::std::string; } name_part_->assign(value); } inline void UninterpretedOption_NamePart::set_name_part(const char* value, size_t size) { - _set_bit(0); - if (name_part_ == &_default_name_part_) { + set_has_name_part(); + if (name_part_ == &::google::protobuf::internal::kEmptyString) { name_part_ = new ::std::string; } name_part_->assign(reinterpret_cast<const char*>(value), size); } inline ::std::string* UninterpretedOption_NamePart::mutable_name_part() { - _set_bit(0); - if (name_part_ == &_default_name_part_) { + set_has_name_part(); + if (name_part_ == &::google::protobuf::internal::kEmptyString) { name_part_ = new ::std::string; } return name_part_; } +inline ::std::string* UninterpretedOption_NamePart::release_name_part() { + clear_has_name_part(); + if (name_part_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = name_part_; + name_part_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} // required bool is_extension = 2; inline bool UninterpretedOption_NamePart::has_is_extension() const { - return _has_bit(1); + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void UninterpretedOption_NamePart::set_has_is_extension() { + _has_bits_[0] |= 0x00000002u; +} +inline void UninterpretedOption_NamePart::clear_has_is_extension() { + _has_bits_[0] &= ~0x00000002u; } inline void UninterpretedOption_NamePart::clear_is_extension() { is_extension_ = false; - _clear_bit(1); + clear_has_is_extension(); } inline bool UninterpretedOption_NamePart::is_extension() const { return is_extension_; } inline void UninterpretedOption_NamePart::set_is_extension(bool value) { - _set_bit(1); + set_has_is_extension(); is_extension_ = value; } @@ -4213,135 +4899,326 @@ UninterpretedOption::mutable_name() { // optional string identifier_value = 3; inline bool UninterpretedOption::has_identifier_value() const { - return _has_bit(1); + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void UninterpretedOption::set_has_identifier_value() { + _has_bits_[0] |= 0x00000002u; +} +inline void UninterpretedOption::clear_has_identifier_value() { + _has_bits_[0] &= ~0x00000002u; } inline void UninterpretedOption::clear_identifier_value() { - if (identifier_value_ != &_default_identifier_value_) { + if (identifier_value_ != &::google::protobuf::internal::kEmptyString) { identifier_value_->clear(); } - _clear_bit(1); + clear_has_identifier_value(); } inline const ::std::string& UninterpretedOption::identifier_value() const { return *identifier_value_; } inline void UninterpretedOption::set_identifier_value(const ::std::string& value) { - _set_bit(1); - if (identifier_value_ == &_default_identifier_value_) { + set_has_identifier_value(); + if (identifier_value_ == &::google::protobuf::internal::kEmptyString) { identifier_value_ = new ::std::string; } identifier_value_->assign(value); } inline void UninterpretedOption::set_identifier_value(const char* value) { - _set_bit(1); - if (identifier_value_ == &_default_identifier_value_) { + set_has_identifier_value(); + if (identifier_value_ == &::google::protobuf::internal::kEmptyString) { identifier_value_ = new ::std::string; } identifier_value_->assign(value); } inline void UninterpretedOption::set_identifier_value(const char* value, size_t size) { - _set_bit(1); - if (identifier_value_ == &_default_identifier_value_) { + set_has_identifier_value(); + if (identifier_value_ == &::google::protobuf::internal::kEmptyString) { identifier_value_ = new ::std::string; } identifier_value_->assign(reinterpret_cast<const char*>(value), size); } inline ::std::string* UninterpretedOption::mutable_identifier_value() { - _set_bit(1); - if (identifier_value_ == &_default_identifier_value_) { + set_has_identifier_value(); + if (identifier_value_ == &::google::protobuf::internal::kEmptyString) { identifier_value_ = new ::std::string; } return identifier_value_; } +inline ::std::string* UninterpretedOption::release_identifier_value() { + clear_has_identifier_value(); + if (identifier_value_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = identifier_value_; + identifier_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} // optional uint64 positive_int_value = 4; inline bool UninterpretedOption::has_positive_int_value() const { - return _has_bit(2); + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void UninterpretedOption::set_has_positive_int_value() { + _has_bits_[0] |= 0x00000004u; +} +inline void UninterpretedOption::clear_has_positive_int_value() { + _has_bits_[0] &= ~0x00000004u; } inline void UninterpretedOption::clear_positive_int_value() { positive_int_value_ = GOOGLE_ULONGLONG(0); - _clear_bit(2); + clear_has_positive_int_value(); } inline ::google::protobuf::uint64 UninterpretedOption::positive_int_value() const { return positive_int_value_; } inline void UninterpretedOption::set_positive_int_value(::google::protobuf::uint64 value) { - _set_bit(2); + set_has_positive_int_value(); positive_int_value_ = value; } // optional int64 negative_int_value = 5; inline bool UninterpretedOption::has_negative_int_value() const { - return _has_bit(3); + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void UninterpretedOption::set_has_negative_int_value() { + _has_bits_[0] |= 0x00000008u; +} +inline void UninterpretedOption::clear_has_negative_int_value() { + _has_bits_[0] &= ~0x00000008u; } inline void UninterpretedOption::clear_negative_int_value() { negative_int_value_ = GOOGLE_LONGLONG(0); - _clear_bit(3); + clear_has_negative_int_value(); } inline ::google::protobuf::int64 UninterpretedOption::negative_int_value() const { return negative_int_value_; } inline void UninterpretedOption::set_negative_int_value(::google::protobuf::int64 value) { - _set_bit(3); + set_has_negative_int_value(); negative_int_value_ = value; } // optional double double_value = 6; inline bool UninterpretedOption::has_double_value() const { - return _has_bit(4); + return (_has_bits_[0] & 0x00000010u) != 0; +} +inline void UninterpretedOption::set_has_double_value() { + _has_bits_[0] |= 0x00000010u; +} +inline void UninterpretedOption::clear_has_double_value() { + _has_bits_[0] &= ~0x00000010u; } inline void UninterpretedOption::clear_double_value() { double_value_ = 0; - _clear_bit(4); + clear_has_double_value(); } inline double UninterpretedOption::double_value() const { return double_value_; } inline void UninterpretedOption::set_double_value(double value) { - _set_bit(4); + set_has_double_value(); double_value_ = value; } // optional bytes string_value = 7; inline bool UninterpretedOption::has_string_value() const { - return _has_bit(5); + return (_has_bits_[0] & 0x00000020u) != 0; +} +inline void UninterpretedOption::set_has_string_value() { + _has_bits_[0] |= 0x00000020u; +} +inline void UninterpretedOption::clear_has_string_value() { + _has_bits_[0] &= ~0x00000020u; } inline void UninterpretedOption::clear_string_value() { - if (string_value_ != &_default_string_value_) { + if (string_value_ != &::google::protobuf::internal::kEmptyString) { string_value_->clear(); } - _clear_bit(5); + clear_has_string_value(); } inline const ::std::string& UninterpretedOption::string_value() const { return *string_value_; } inline void UninterpretedOption::set_string_value(const ::std::string& value) { - _set_bit(5); - if (string_value_ == &_default_string_value_) { + set_has_string_value(); + if (string_value_ == &::google::protobuf::internal::kEmptyString) { string_value_ = new ::std::string; } string_value_->assign(value); } inline void UninterpretedOption::set_string_value(const char* value) { - _set_bit(5); - if (string_value_ == &_default_string_value_) { + set_has_string_value(); + if (string_value_ == &::google::protobuf::internal::kEmptyString) { string_value_ = new ::std::string; } string_value_->assign(value); } inline void UninterpretedOption::set_string_value(const void* value, size_t size) { - _set_bit(5); - if (string_value_ == &_default_string_value_) { + set_has_string_value(); + if (string_value_ == &::google::protobuf::internal::kEmptyString) { string_value_ = new ::std::string; } string_value_->assign(reinterpret_cast<const char*>(value), size); } inline ::std::string* UninterpretedOption::mutable_string_value() { - _set_bit(5); - if (string_value_ == &_default_string_value_) { + set_has_string_value(); + if (string_value_ == &::google::protobuf::internal::kEmptyString) { string_value_ = new ::std::string; } return string_value_; } +inline ::std::string* UninterpretedOption::release_string_value() { + clear_has_string_value(); + if (string_value_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = string_value_; + string_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} + +// optional string aggregate_value = 8; +inline bool UninterpretedOption::has_aggregate_value() const { + return (_has_bits_[0] & 0x00000040u) != 0; +} +inline void UninterpretedOption::set_has_aggregate_value() { + _has_bits_[0] |= 0x00000040u; +} +inline void UninterpretedOption::clear_has_aggregate_value() { + _has_bits_[0] &= ~0x00000040u; +} +inline void UninterpretedOption::clear_aggregate_value() { + if (aggregate_value_ != &::google::protobuf::internal::kEmptyString) { + aggregate_value_->clear(); + } + clear_has_aggregate_value(); +} +inline const ::std::string& UninterpretedOption::aggregate_value() const { + return *aggregate_value_; +} +inline void UninterpretedOption::set_aggregate_value(const ::std::string& value) { + set_has_aggregate_value(); + if (aggregate_value_ == &::google::protobuf::internal::kEmptyString) { + aggregate_value_ = new ::std::string; + } + aggregate_value_->assign(value); +} +inline void UninterpretedOption::set_aggregate_value(const char* value) { + set_has_aggregate_value(); + if (aggregate_value_ == &::google::protobuf::internal::kEmptyString) { + aggregate_value_ = new ::std::string; + } + aggregate_value_->assign(value); +} +inline void UninterpretedOption::set_aggregate_value(const char* value, size_t size) { + set_has_aggregate_value(); + if (aggregate_value_ == &::google::protobuf::internal::kEmptyString) { + aggregate_value_ = new ::std::string; + } + aggregate_value_->assign(reinterpret_cast<const char*>(value), size); +} +inline ::std::string* UninterpretedOption::mutable_aggregate_value() { + set_has_aggregate_value(); + if (aggregate_value_ == &::google::protobuf::internal::kEmptyString) { + aggregate_value_ = new ::std::string; + } + return aggregate_value_; +} +inline ::std::string* UninterpretedOption::release_aggregate_value() { + clear_has_aggregate_value(); + if (aggregate_value_ == &::google::protobuf::internal::kEmptyString) { + return NULL; + } else { + ::std::string* temp = aggregate_value_; + aggregate_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + return temp; + } +} + +// ------------------------------------------------------------------- + +// SourceCodeInfo_Location + +// repeated int32 path = 1 [packed = true]; +inline int SourceCodeInfo_Location::path_size() const { + return path_.size(); +} +inline void SourceCodeInfo_Location::clear_path() { + path_.Clear(); +} +inline ::google::protobuf::int32 SourceCodeInfo_Location::path(int index) const { + return path_.Get(index); +} +inline void SourceCodeInfo_Location::set_path(int index, ::google::protobuf::int32 value) { + path_.Set(index, value); +} +inline void SourceCodeInfo_Location::add_path(::google::protobuf::int32 value) { + path_.Add(value); +} +inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >& +SourceCodeInfo_Location::path() const { + return path_; +} +inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >* +SourceCodeInfo_Location::mutable_path() { + return &path_; +} + +// repeated int32 span = 2 [packed = true]; +inline int SourceCodeInfo_Location::span_size() const { + return span_.size(); +} +inline void SourceCodeInfo_Location::clear_span() { + span_.Clear(); +} +inline ::google::protobuf::int32 SourceCodeInfo_Location::span(int index) const { + return span_.Get(index); +} +inline void SourceCodeInfo_Location::set_span(int index, ::google::protobuf::int32 value) { + span_.Set(index, value); +} +inline void SourceCodeInfo_Location::add_span(::google::protobuf::int32 value) { + span_.Add(value); +} +inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >& +SourceCodeInfo_Location::span() const { + return span_; +} +inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >* +SourceCodeInfo_Location::mutable_span() { + return &span_; +} + +// ------------------------------------------------------------------- + +// SourceCodeInfo + +// repeated .google.protobuf.SourceCodeInfo.Location location = 1; +inline int SourceCodeInfo::location_size() const { + return location_.size(); +} +inline void SourceCodeInfo::clear_location() { + location_.Clear(); +} +inline const ::google::protobuf::SourceCodeInfo_Location& SourceCodeInfo::location(int index) const { + return location_.Get(index); +} +inline ::google::protobuf::SourceCodeInfo_Location* SourceCodeInfo::mutable_location(int index) { + return location_.Mutable(index); +} +inline ::google::protobuf::SourceCodeInfo_Location* SourceCodeInfo::add_location() { + return location_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location >& +SourceCodeInfo::location() const { + return location_; +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location >* +SourceCodeInfo::mutable_location() { + return &location_; +} // @@protoc_insertion_point(namespace_scope) diff --git a/third_party/protobuf/src/google/protobuf/descriptor.proto b/third_party/protobuf/src/google/protobuf/descriptor.proto index c07815b..1b419b9 100644 --- a/third_party/protobuf/src/google/protobuf/descriptor.proto +++ b/third_party/protobuf/src/google/protobuf/descriptor.proto @@ -67,6 +67,12 @@ message FileDescriptorProto { repeated FieldDescriptorProto extension = 7; optional FileOptions options = 8; + + // This field contains optional information about the original source code. + // You may safely remove this entire field whithout harming runtime + // functionality of the descriptors -- the information is needed only by + // development tools. + optional SourceCodeInfo source_code_info = 9; } // Describes a message type. @@ -251,6 +257,12 @@ message FileOptions { // when LITE_RUNTIME is in use. optional bool retain_unknown_fields = 11 [default=false]; + // If set true, then the Java code generator will generate equals() and + // hashCode() methods for all messages defined in the .proto file. This is + // purely a speed optimization, as the AbstractMessage base class includes + // reflection-based implementations of these methods. + optional bool java_generate_equals_and_hash = 20 [default=false]; + // Generated classes can be optimized for speed or code size. enum OptimizeMode { SPEED = 1; // Generate complete code for parsing, serialization, @@ -270,13 +282,12 @@ message FileOptions { // early versions of proto2. // // Generic services are now considered deprecated in favor of using plugins - // that generate code specific to your particular RPC system. If you are - // using such a plugin, set these to false. In the future, we may change - // the default to false, so if you explicitly want generic services, you - // should explicitly set these to true. - optional bool cc_generic_services = 16 [default=true]; - optional bool java_generic_services = 17 [default=true]; - optional bool py_generic_services = 18 [default=true]; + // that generate code specific to your particular RPC system. Therefore, + // these default to false. Old code which depends on generic services should + // explicitly set them to true. + optional bool cc_generic_services = 16 [default=false]; + optional bool java_generic_services = 17 [default=false]; + optional bool py_generic_services = 18 [default=false]; // The parser stores options it doesn't recognize here. See above. repeated UninterpretedOption uninterpreted_option = 999; @@ -436,4 +447,93 @@ message UninterpretedOption { optional int64 negative_int_value = 5; optional double double_value = 6; optional bytes string_value = 7; + optional string aggregate_value = 8; +} + +// =================================================================== +// Optional source code info + +// Encapsulates information about the original source file from which a +// FileDescriptorProto was generated. +message SourceCodeInfo { + // A Location identifies a piece of source code in a .proto file which + // corresponds to a particular definition. This information is intended + // to be useful to IDEs, code indexers, documentation generators, and similar + // tools. + // + // For example, say we have a file like: + // message Foo { + // optional string foo = 1; + // } + // Let's look at just the field definition: + // optional string foo = 1; + // ^ ^^ ^^ ^ ^^^ + // a bc de f ghi + // We have the following locations: + // span path represents + // [a,i) [ 4, 0, 2, 0 ] The whole field definition. + // [a,b) [ 4, 0, 2, 0, 4 ] The label (optional). + // [c,d) [ 4, 0, 2, 0, 5 ] The type (string). + // [e,f) [ 4, 0, 2, 0, 1 ] The name (foo). + // [g,h) [ 4, 0, 2, 0, 3 ] The number (1). + // + // Notes: + // - A location may refer to a repeated field itself (i.e. not to any + // particular index within it). This is used whenever a set of elements are + // logically enclosed in a single code segment. For example, an entire + // extend block (possibly containing multiple extension definitions) will + // have an outer location whose path refers to the "extensions" repeated + // field without an index. + // - Multiple locations may have the same path. This happens when a single + // logical declaration is spread out across multiple places. The most + // obvious example is the "extend" block again -- there may be multiple + // extend blocks in the same scope, each of which will have the same path. + // - A location's span is not always a subset of its parent's span. For + // example, the "extendee" of an extension declaration appears at the + // beginning of the "extend" block and is shared by all extensions within + // the block. + // - Just because a location's span is a subset of some other location's span + // does not mean that it is a descendent. For example, a "group" defines + // both a type and a field in a single declaration. Thus, the locations + // corresponding to the type and field and their components will overlap. + // - Code which tries to interpret locations should probably be designed to + // ignore those that it doesn't understand, as more types of locations could + // be recorded in the future. + repeated Location location = 1; + message Location { + // Identifies which part of the FileDescriptorProto was defined at this + // location. + // + // Each element is a field number or an index. They form a path from + // the root FileDescriptorProto to the place where the definition. For + // example, this path: + // [ 4, 3, 2, 7, 1 ] + // refers to: + // file.message_type(3) // 4, 3 + // .field(7) // 2, 7 + // .name() // 1 + // This is because FileDescriptorProto.message_type has field number 4: + // repeated DescriptorProto message_type = 4; + // and DescriptorProto.field has field number 2: + // repeated FieldDescriptorProto field = 2; + // and FieldDescriptorProto.name has field number 1: + // optional string name = 1; + // + // Thus, the above path gives the location of a field name. If we removed + // the last element: + // [ 4, 3, 2, 7 ] + // this path refers to the whole field declaration (from the beginning + // of the label to the terminating semicolon). + repeated int32 path = 1 [packed=true]; + + // Always has exactly three or four elements: start line, start column, + // end line (optional, otherwise assumed same as start line), end column. + // These are packed into a single field for efficiency. Note that line + // and column numbers are zero-based -- typically you will want to add + // 1 to each before displaying to a user. + repeated int32 span = 2 [packed=true]; + + // TODO(kenton): Record comments appearing before and after the + // declaration. + } } diff --git a/third_party/protobuf/src/google/protobuf/descriptor_database.cc b/third_party/protobuf/src/google/protobuf/descriptor_database.cc index 95708d9..23e48a6 100644 --- a/third_party/protobuf/src/google/protobuf/descriptor_database.cc +++ b/third_party/protobuf/src/google/protobuf/descriptor_database.cc @@ -101,7 +101,7 @@ bool SimpleDescriptorDatabase::DescriptorIndex<Value>::AddSymbol( if (iter == by_symbol_.end()) { // Apparently the map is currently empty. Just insert and be done with it. - by_symbol_.insert(make_pair(name, value)); + by_symbol_.insert(typename map<string, Value>::value_type(name, value)); return true; } @@ -128,7 +128,7 @@ bool SimpleDescriptorDatabase::DescriptorIndex<Value>::AddSymbol( // Insert the new symbol using the iterator as a hint, the new entry will // appear immediately before the one the iterator is pointing at. - by_symbol_.insert(iter, make_pair(name, value)); + by_symbol_.insert(iter, typename map<string, Value>::value_type(name, value)); return true; } diff --git a/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc b/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc index d70c9bf..55aebfd 100644 --- a/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc +++ b/third_party/protobuf/src/google/protobuf/descriptor_unittest.cc @@ -2212,6 +2212,45 @@ TEST(CustomOptions, MessageOptionThreeFieldsSet) { EXPECT_EQ(1234, options.GetExtension(protobuf_unittest::complex_opt1).foo()); } +// Check that aggregate options were parsed and saved correctly in +// the appropriate descriptors. +TEST(CustomOptions, AggregateOptions) { + const Descriptor* msg = protobuf_unittest::AggregateMessage::descriptor(); + const FileDescriptor* file = msg->file(); + const FieldDescriptor* field = msg->FindFieldByName("fieldname"); + const EnumDescriptor* enumd = file->FindEnumTypeByName("AggregateEnum"); + const EnumValueDescriptor* enumv = enumd->FindValueByName("VALUE"); + const ServiceDescriptor* service = file->FindServiceByName( + "AggregateService"); + const MethodDescriptor* method = service->FindMethodByName("Method"); + + // Tests for the different types of data embedded in fileopt + const protobuf_unittest::Aggregate& file_options = + file->options().GetExtension(protobuf_unittest::fileopt); + EXPECT_EQ(100, file_options.i()); + EXPECT_EQ("FileAnnotation", file_options.s()); + EXPECT_EQ("NestedFileAnnotation", file_options.sub().s()); + EXPECT_EQ("FileExtensionAnnotation", + file_options.file().GetExtension(protobuf_unittest::fileopt).s()); + EXPECT_EQ("EmbeddedMessageSetElement", + file_options.mset().GetExtension( + protobuf_unittest::AggregateMessageSetElement + ::message_set_extension).s()); + + // Simple tests for all the other types of annotations + EXPECT_EQ("MessageAnnotation", + msg->options().GetExtension(protobuf_unittest::msgopt).s()); + EXPECT_EQ("FieldAnnotation", + field->options().GetExtension(protobuf_unittest::fieldopt).s()); + EXPECT_EQ("EnumAnnotation", + enumd->options().GetExtension(protobuf_unittest::enumopt).s()); + EXPECT_EQ("EnumValueAnnotation", + enumv->options().GetExtension(protobuf_unittest::enumvalopt).s()); + EXPECT_EQ("ServiceAnnotation", + service->options().GetExtension(protobuf_unittest::serviceopt).s()); + EXPECT_EQ("MethodAnnotation", + method->options().GetExtension(protobuf_unittest::methodopt).s()); +} // =================================================================== @@ -3425,25 +3464,50 @@ TEST_F(ValidationErrorTest, StringOptionValueIsNotString) { "string option \"foo\".\n"); } -TEST_F(ValidationErrorTest, TryingToSetMessageValuedOption) { +// Helper function for tests that check for aggregate value parsing +// errors. The "value" argument is embedded inside the +// "uninterpreted_option" portion of the result. +static string EmbedAggregateValue(const char* value) { + return strings::Substitute( + "name: \"foo.proto\" " + "dependency: \"google/protobuf/descriptor.proto\" " + "message_type { name: \"Foo\" } " + "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL " + " type: TYPE_MESSAGE type_name: \"Foo\" " + " extendee: \"google.protobuf.FileOptions\" }" + "options { uninterpreted_option { name { name_part: \"foo\" " + " is_extension: true } " + " $0 } }", + value); +} + +TEST_F(ValidationErrorTest, AggregateValueNotFound) { BuildDescriptorMessagesInTestPool(); BuildFileWithErrors( - "name: \"foo.proto\" " - "dependency: \"google/protobuf/descriptor.proto\" " - "message_type { " - " name: \"TestMessage\" " - " field { name:\"baz\" number:1 label:LABEL_OPTIONAL type:TYPE_STRING }" - "}" - "extension { name: \"bar\" number: 7672757 label: LABEL_OPTIONAL " - " type: TYPE_MESSAGE type_name: \"TestMessage\" " - " extendee: \"google.protobuf.FileOptions\" }" - "options { uninterpreted_option { name { name_part: \"bar\" " - " is_extension: true } " - " identifier_value: \"QUUX\" } }", + EmbedAggregateValue("string_value: \"\""), + "foo.proto: foo.proto: OPTION_VALUE: Option \"foo\" is a message. " + "To set the entire message, use syntax like " + "\"foo = { <proto text format> }\". To set fields within it, use " + "syntax like \"foo.foo = value\".\n"); +} - "foo.proto: foo.proto: OPTION_NAME: Option field \"(bar)\" cannot be of " - "message type.\n"); +TEST_F(ValidationErrorTest, AggregateValueParseError) { + BuildDescriptorMessagesInTestPool(); + + BuildFileWithErrors( + EmbedAggregateValue("aggregate_value: \"1+2\""), + "foo.proto: foo.proto: OPTION_VALUE: Error while parsing option " + "value for \"foo\": Expected identifier.\n"); +} + +TEST_F(ValidationErrorTest, AggregateValueUnknownFields) { + BuildDescriptorMessagesInTestPool(); + + BuildFileWithErrors( + EmbedAggregateValue("aggregate_value: \"x:100\""), + "foo.proto: foo.proto: OPTION_VALUE: Error while parsing option " + "value for \"foo\": Message type \"Foo\" has no field named \"x\".\n"); } TEST_F(ValidationErrorTest, NotLiteImportsLite) { @@ -3483,7 +3547,11 @@ TEST_F(ValidationErrorTest, LiteExtendsNotLite) { TEST_F(ValidationErrorTest, NoLiteServices) { BuildFileWithErrors( "name: \"foo.proto\" " - "options { optimize_for: LITE_RUNTIME } " + "options {" + " optimize_for: LITE_RUNTIME" + " cc_generic_services: true" + " java_generic_services: true" + "} " "service { name: \"Foo\" }", "foo.proto: Foo: NAME: Files with optimize_for = LITE_RUNTIME cannot " @@ -3497,7 +3565,7 @@ TEST_F(ValidationErrorTest, NoLiteServices) { " cc_generic_services: false" " java_generic_services: false" "} " - "service { name: \"Foo\" }"); + "service { name: \"Bar\" }"); } TEST_F(ValidationErrorTest, RollbackAfterError) { diff --git a/third_party/protobuf/src/google/protobuf/extension_set.cc b/third_party/protobuf/src/google/protobuf/extension_set.cc index c1b59e8..dbb0915 100644 --- a/third_party/protobuf/src/google/protobuf/extension_set.cc +++ b/third_party/protobuf/src/google/protobuf/extension_set.cc @@ -186,6 +186,18 @@ int ExtensionSet::ExtensionSize(int number) const { return iter->second.GetSize(); } +FieldType ExtensionSet::ExtensionType(int number) const { + map<int, Extension>::const_iterator iter = extensions_.find(number); + if (iter == extensions_.end()) { + GOOGLE_LOG(DFATAL) << "Don't lookup extension types if they aren't present (1). "; + return 0; + } + if (iter->second.is_cleared) { + GOOGLE_LOG(DFATAL) << "Don't lookup extension types if they aren't present (2). "; + } + return iter->second.type; +} + void ExtensionSet::ClearExtension(int number) { map<int, Extension>::iterator iter = extensions_.find(number); if (iter == extensions_.end()) return; diff --git a/third_party/protobuf/src/google/protobuf/extension_set.h b/third_party/protobuf/src/google/protobuf/extension_set.h index 1ca9de7..68ce423 100644 --- a/third_party/protobuf/src/google/protobuf/extension_set.h +++ b/third_party/protobuf/src/google/protobuf/extension_set.h @@ -39,11 +39,11 @@ #define GOOGLE_PROTOBUF_EXTENSION_SET_H__ #include <vector> -#include <stack> #include <map> #include <utility> #include <string> + #include <google/protobuf/stubs/common.h> namespace google { @@ -214,6 +214,7 @@ class LIBPROTOBUF_EXPORT ExtensionSet { bool Has(int number) const; int ExtensionSize(int number) const; // Size of a repeated extension. + FieldType ExtensionType(int number) const; void ClearExtension(int number); // singular fields ------------------------------------------------- @@ -453,6 +454,7 @@ class LIBPROTOBUF_EXPORT ExtensionSet { int SpaceUsedExcludingSelf() const; }; + // Gets the extension with the given number, creating it if it does not // already exist. Returns true if the extension did not already exist. bool MaybeNewExtension(int number, const FieldDescriptor* descriptor, diff --git a/third_party/protobuf/src/google/protobuf/generated_message_reflection.cc b/third_party/protobuf/src/google/protobuf/generated_message_reflection.cc index 9c933fe..226e951 100644 --- a/third_party/protobuf/src/google/protobuf/generated_message_reflection.cc +++ b/third_party/protobuf/src/google/protobuf/generated_message_reflection.cc @@ -45,8 +45,6 @@ namespace google { namespace protobuf { namespace internal { -namespace { const string kEmptyString; } - bool ParseNamedEnum(const EnumDescriptor* descriptor, const string& name, int* value) { @@ -57,7 +55,6 @@ bool ParseNamedEnum(const EnumDescriptor* descriptor, } const string& NameOfEnum(const EnumDescriptor* descriptor, int value) { - static string kEmptyString; const EnumValueDescriptor* d = descriptor->FindValueByNumber(value); return (d == NULL ? kEmptyString : d->name()); } diff --git a/third_party/protobuf/src/google/protobuf/generated_message_util.cc b/third_party/protobuf/src/google/protobuf/generated_message_util.cc index 7ac015d..76e547b 100644 --- a/third_party/protobuf/src/google/protobuf/generated_message_util.cc +++ b/third_party/protobuf/src/google/protobuf/generated_message_util.cc @@ -47,6 +47,8 @@ double NaN() { return std::numeric_limits<double>::quiet_NaN(); } +const ::std::string kEmptyString; + } // namespace internal } // namespace protobuf diff --git a/third_party/protobuf/src/google/protobuf/generated_message_util.h b/third_party/protobuf/src/google/protobuf/generated_message_util.h index daa16f7..1a2343d 100644 --- a/third_party/protobuf/src/google/protobuf/generated_message_util.h +++ b/third_party/protobuf/src/google/protobuf/generated_message_util.h @@ -38,6 +38,8 @@ #ifndef GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__ #define GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__ +#include <string> + #include <google/protobuf/stubs/common.h> @@ -66,8 +68,11 @@ namespace internal { // Constants for special floating point values. -LIBPROTOBUF_EXPORT double Infinity(); -LIBPROTOBUF_EXPORT double NaN(); +double Infinity(); +double NaN(); + +// Constant used for empty default strings. +extern const ::std::string kEmptyString; } // namespace internal diff --git a/third_party/protobuf/src/google/protobuf/io/coded_stream.cc b/third_party/protobuf/src/google/protobuf/io/coded_stream.cc index 6a91a13..57d486f 100644 --- a/third_party/protobuf/src/google/protobuf/io/coded_stream.cc +++ b/third_party/protobuf/src/google/protobuf/io/coded_stream.cc @@ -56,6 +56,15 @@ static const int kMaxVarintBytes = 10; static const int kMaxVarint32Bytes = 5; +inline bool NextNonEmpty(ZeroCopyInputStream* input, + const void** data, int* size) { + bool success; + do { + success = input->Next(data, size); + } while (success && *size == 0); + return success; +} + } // namespace // CodedInputStream ================================================== @@ -489,7 +498,7 @@ bool CodedInputStream::Refresh() { const void* void_buffer; int buffer_size; - if (input_->Next(&void_buffer, &buffer_size)) { + if (NextNonEmpty(input_, &void_buffer, &buffer_size)) { buffer_ = reinterpret_cast<const uint8*>(void_buffer); buffer_end_ = buffer_ + buffer_size; GOOGLE_CHECK_GE(buffer_size, 0); diff --git a/third_party/protobuf/src/google/protobuf/io/coded_stream.h b/third_party/protobuf/src/google/protobuf/io/coded_stream.h index 93effc8..1b6b4e1 100644 --- a/third_party/protobuf/src/google/protobuf/io/coded_stream.h +++ b/third_party/protobuf/src/google/protobuf/io/coded_stream.h @@ -129,8 +129,8 @@ #endif #include <google/protobuf/stubs/common.h> -namespace google { +namespace google { namespace protobuf { class DescriptorPool; @@ -567,7 +567,7 @@ class LIBPROTOBUF_EXPORT CodedInputStream { // char text[] = "Hello world!"; // // int coded_size = sizeof(magic_number) + -// CodedOutputStream::Varint32Size(strlen(text)) + +// CodedOutputStream::VarintSize32(strlen(text)) + // strlen(text); // // uint8* buffer = @@ -990,12 +990,12 @@ inline int CodedOutputStream::VarintSize32SignExtended(int32 value) { } inline void CodedOutputStream::WriteString(const string& str) { - WriteRaw(str.data(), str.size()); + WriteRaw(str.data(), static_cast<int>(str.size())); } inline uint8* CodedOutputStream::WriteStringToArray( const string& str, uint8* target) { - return WriteRawToArray(str.data(), str.size(), target); + return WriteRawToArray(str.data(), static_cast<int>(str.size()), target); } inline int CodedOutputStream::ByteCount() const { @@ -1093,10 +1093,10 @@ inline CodedInputStream::~CodedInputStream() { } // namespace io } // namespace protobuf -} // namespace google #if defined(_MSC_VER) && _MSC_VER >= 1300 #pragma runtime_checks("c", restore) #endif // _MSC_VER +} // namespace google #endif // GOOGLE_PROTOBUF_IO_CODED_STREAM_H__ diff --git a/third_party/protobuf/src/google/protobuf/io/coded_stream_unittest.cc b/third_party/protobuf/src/google/protobuf/io/coded_stream_unittest.cc index 7d298332..ff268ab 100644 --- a/third_party/protobuf/src/google/protobuf/io/coded_stream_unittest.cc +++ b/third_party/protobuf/src/google/protobuf/io/coded_stream_unittest.cc @@ -208,6 +208,33 @@ TEST_2D(CodedStreamTest, ReadTag, kVarintCases, kBlockSizes) { EXPECT_EQ(kVarintCases_case.size, input.ByteCount()); } +// This is the regression test that verifies that there is no issues +// with the empty input buffers handling. +TEST_F(CodedStreamTest, EmptyInputBeforeEos) { + class In : public ZeroCopyInputStream { + public: + In() : count_(0) {} + private: + virtual bool Next(const void** data, int* size) { + *data = NULL; + *size = 0; + return count_++ < 2; + } + virtual void BackUp(int count) { + GOOGLE_LOG(FATAL) << "Tests never call this."; + } + virtual bool Skip(int count) { + GOOGLE_LOG(FATAL) << "Tests never call this."; + return false; + } + virtual int64 ByteCount() const { return 0; } + int count_; + } in; + CodedInputStream input(&in); + input.ReadTag(); + EXPECT_TRUE(input.ConsumedEntireMessage()); +} + TEST_1D(CodedStreamTest, ExpectTag, kVarintCases) { // Leave one byte at the beginning of the buffer so we can read it // to force the first buffer to be loaded. @@ -995,6 +1022,7 @@ TEST_F(CodedStreamTest, TotalBytesLimitNotValidMessageEnd) { EXPECT_FALSE(coded_input.ConsumedEntireMessage()); } + TEST_F(CodedStreamTest, RecursionLimit) { ArrayInputStream input(buffer_, sizeof(buffer_)); CodedInputStream coded_input(&input); diff --git a/third_party/protobuf/src/google/protobuf/io/gzip_stream.cc b/third_party/protobuf/src/google/protobuf/io/gzip_stream.cc index 84d277f..0f1ff87 100644 --- a/third_party/protobuf/src/google/protobuf/io/gzip_stream.cc +++ b/third_party/protobuf/src/google/protobuf/io/gzip_stream.cc @@ -73,6 +73,17 @@ GzipInputStream::~GzipInputStream() { zerror_ = inflateEnd(&zcontext_); } +static inline int internalInflateInit2( + z_stream* zcontext, GzipInputStream::Format format) { + int windowBitsFormat = 0; + switch (format) { + case GzipInputStream::GZIP: windowBitsFormat = 16; break; + case GzipInputStream::AUTO: windowBitsFormat = 32; break; + case GzipInputStream::ZLIB: windowBitsFormat = 0; break; + } + return inflateInit2(zcontext, /* windowBits */15 | windowBitsFormat); +} + int GzipInputStream::Inflate(int flush) { if ((zerror_ == Z_OK) && (zcontext_.avail_out == 0)) { // previous inflate filled output buffer. don't change input params yet. @@ -89,14 +100,7 @@ int GzipInputStream::Inflate(int flush) { zcontext_.next_in = static_cast<Bytef*>(const_cast<void*>(in)); zcontext_.avail_in = in_size; if (first) { - int windowBitsFormat = 0; - switch (format_) { - case GZIP: windowBitsFormat = 16; break; - case AUTO: windowBitsFormat = 32; break; - case ZLIB: windowBitsFormat = 0; break; - } - int error = inflateInit2(&zcontext_, - /* windowBits */15 | windowBitsFormat); + int error = internalInflateInit2(&zcontext_, format_); if (error != Z_OK) { return error; } @@ -127,9 +131,21 @@ bool GzipInputStream::Next(const void** data, int* size) { return true; } if (zerror_ == Z_STREAM_END) { - *data = NULL; - *size = 0; - return false; + if (zcontext_.next_out != NULL) { + // sub_stream_ may have concatenated streams to follow + zerror_ = inflateEnd(&zcontext_); + if (zerror_ != Z_OK) { + return false; + } + zerror_ = internalInflateInit2(&zcontext_, format_); + if (zerror_ != Z_OK) { + return false; + } + } else { + *data = NULL; + *size = 0; + return false; + } } zerror_ = Inflate(Z_NO_FLUSH); if ((zerror_ == Z_STREAM_END) && (zcontext_.next_out == NULL)) { @@ -251,8 +267,7 @@ int GzipOutputStream::Deflate(int flush) { } error = deflate(&zcontext_, flush); } while (error == Z_OK && zcontext_.avail_out == 0); - if (((flush == Z_FULL_FLUSH) || (flush == Z_FINISH)) - && (zcontext_.avail_out != sub_data_size_)) { + if ((flush == Z_FULL_FLUSH) || (flush == Z_FINISH)) { // Notify lower layer of data. sub_stream_->BackUp(zcontext_.avail_out); // We don't own the buffer anymore. diff --git a/third_party/protobuf/src/google/protobuf/io/printer.cc b/third_party/protobuf/src/google/protobuf/io/printer.cc index c7d3074..9ab90de 100644 --- a/third_party/protobuf/src/google/protobuf/io/printer.cc +++ b/third_party/protobuf/src/google/protobuf/io/printer.cc @@ -132,6 +132,17 @@ void Printer::Print(const char* text, Print(vars, text); } +void Printer::Print(const char* text, + const char* variable1, const string& value1, + const char* variable2, const string& value2, + const char* variable3, const string& value3) { + map<string, string> vars; + vars[variable1] = value1; + vars[variable2] = value2; + vars[variable3] = value3; + Print(vars, text); +} + void Printer::Indent() { indent_ += " "; } diff --git a/third_party/protobuf/src/google/protobuf/io/printer.h b/third_party/protobuf/src/google/protobuf/io/printer.h index de08538..5be4854 100644 --- a/third_party/protobuf/src/google/protobuf/io/printer.h +++ b/third_party/protobuf/src/google/protobuf/io/printer.h @@ -82,7 +82,11 @@ class LIBPROTOBUF_EXPORT Printer { // Like the first Print(), except the substitutions are given as parameters. void Print(const char* text, const char* variable1, const string& value1, const char* variable2, const string& value2); - // TODO(kenton): Overloaded versions with more variables? Two seems + // Like the first Print(), except the substitutions are given as parameters. + void Print(const char* text, const char* variable1, const string& value1, + const char* variable2, const string& value2, + const char* variable3, const string& value3); + // TODO(kenton): Overloaded versions with more variables? Three seems // to be enough. // Indent text by two spaces. After calling Indent(), two spaces will be diff --git a/third_party/protobuf/src/google/protobuf/io/tokenizer.cc b/third_party/protobuf/src/google/protobuf/io/tokenizer.cc index 38fa351..513831d 100644 --- a/third_party/protobuf/src/google/protobuf/io/tokenizer.cc +++ b/third_party/protobuf/src/google/protobuf/io/tokenizer.cc @@ -193,6 +193,7 @@ Tokenizer::Tokenizer(ZeroCopyInputStream* input, current_.line = 0; current_.column = 0; + current_.end_column = 0; current_.type = TYPE_START; Refresh(); @@ -277,6 +278,7 @@ inline void Tokenizer::EndToken() { current_.text.append(buffer_ + token_start_, buffer_pos_ - token_start_); } token_start_ = -1; + current_.end_column = column_; } // ------------------------------------------------------------------- @@ -462,7 +464,7 @@ void Tokenizer::ConsumeBlockComment() { // ------------------------------------------------------------------- bool Tokenizer::Next() { - TokenType last_token_type = current_.type; + previous_ = current_; // Did we skip any characters after the last token? bool skipped_stuff = false; @@ -517,7 +519,7 @@ bool Tokenizer::Next() { if (TryConsumeOne<Digit>()) { // It's a floating-point number. - if (last_token_type == TYPE_IDENTIFIER && !skipped_stuff) { + if (previous_.type == TYPE_IDENTIFIER && !skipped_stuff) { // We don't accept syntax like "blah.123". error_collector_->AddError(line_, column_ - 2, "Need space between identifier and decimal point."); @@ -551,6 +553,7 @@ bool Tokenizer::Next() { current_.text.clear(); current_.line = line_; current_.column = column_; + current_.end_column = column_; return false; } diff --git a/third_party/protobuf/src/google/protobuf/io/tokenizer.h b/third_party/protobuf/src/google/protobuf/io/tokenizer.h index d115161..8f759ab 100644 --- a/third_party/protobuf/src/google/protobuf/io/tokenizer.h +++ b/third_party/protobuf/src/google/protobuf/io/tokenizer.h @@ -122,12 +122,17 @@ class LIBPROTOBUF_EXPORT Tokenizer { // the token within the input stream. They are zero-based. int line; int column; + int end_column; }; // Get the current token. This is updated when Next() is called. Before // the first call to Next(), current() has type TYPE_START and no contents. const Token& current(); + // Return the previous token -- i.e. what current() returned before the + // previous call to Next(). + const Token& previous(); + // Advance to the next token. Returns false if the end of the input is // reached. bool Next(); @@ -180,6 +185,7 @@ class LIBPROTOBUF_EXPORT Tokenizer { GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Tokenizer); Token current_; // Returned by current(). + Token previous_; // Returned by previous(). ZeroCopyInputStream* input_; ErrorCollector* error_collector_; @@ -291,6 +297,10 @@ inline const Tokenizer::Token& Tokenizer::current() { return current_; } +inline const Tokenizer::Token& Tokenizer::previous() { + return previous_; +} + inline void Tokenizer::ParseString(const string& text, string* output) { output->clear(); ParseStringAppend(text, output); diff --git a/third_party/protobuf/src/google/protobuf/io/tokenizer_unittest.cc b/third_party/protobuf/src/google/protobuf/io/tokenizer_unittest.cc index 358ec56..106d080 100644 --- a/third_party/protobuf/src/google/protobuf/io/tokenizer_unittest.cc +++ b/third_party/protobuf/src/google/protobuf/io/tokenizer_unittest.cc @@ -257,6 +257,7 @@ TEST_2D(TokenizerTest, SimpleTokens, kSimpleTokenCases, kBlockSizes) { EXPECT_EQ("", tokenizer.current().text); EXPECT_EQ(0, tokenizer.current().line); EXPECT_EQ(0, tokenizer.current().column); + EXPECT_EQ(0, tokenizer.current().end_column); // Parse the token. ASSERT_TRUE(tokenizer.Next()); @@ -268,6 +269,8 @@ TEST_2D(TokenizerTest, SimpleTokens, kSimpleTokenCases, kBlockSizes) { // Check that it is located at the beginning of the input EXPECT_EQ(0, tokenizer.current().line); EXPECT_EQ(0, tokenizer.current().column); + EXPECT_EQ(kSimpleTokenCases_case.input.size(), + tokenizer.current().end_column); // There should be no more input. EXPECT_FALSE(tokenizer.Next()); @@ -277,6 +280,8 @@ TEST_2D(TokenizerTest, SimpleTokens, kSimpleTokenCases, kBlockSizes) { EXPECT_EQ("", tokenizer.current().text); EXPECT_EQ(0, tokenizer.current().line); EXPECT_EQ(kSimpleTokenCases_case.input.size(), tokenizer.current().column); + EXPECT_EQ(kSimpleTokenCases_case.input.size(), + tokenizer.current().end_column); // There should be no errors. EXPECT_TRUE(error_collector.text_.empty()); @@ -339,76 +344,83 @@ MultiTokenCase kMultiTokenCases[] = { // Test all token types at the same time. { "foo 1 1.2 + 'bar'", { - { Tokenizer::TYPE_IDENTIFIER, "foo" , 0, 0 }, - { Tokenizer::TYPE_INTEGER , "1" , 0, 4 }, - { Tokenizer::TYPE_FLOAT , "1.2" , 0, 6 }, - { Tokenizer::TYPE_SYMBOL , "+" , 0, 10 }, - { Tokenizer::TYPE_STRING , "'bar'", 0, 12 }, - { Tokenizer::TYPE_END , "" , 0, 17 }, + { Tokenizer::TYPE_IDENTIFIER, "foo" , 0, 0, 3 }, + { Tokenizer::TYPE_INTEGER , "1" , 0, 4, 5 }, + { Tokenizer::TYPE_FLOAT , "1.2" , 0, 6, 9 }, + { Tokenizer::TYPE_SYMBOL , "+" , 0, 10, 11 }, + { Tokenizer::TYPE_STRING , "'bar'", 0, 12, 17 }, + { Tokenizer::TYPE_END , "" , 0, 17, 17 }, }}, // Test that consecutive symbols are parsed as separate tokens. { "!@+%", { - { Tokenizer::TYPE_SYMBOL , "!" , 0, 0 }, - { Tokenizer::TYPE_SYMBOL , "@" , 0, 1 }, - { Tokenizer::TYPE_SYMBOL , "+" , 0, 2 }, - { Tokenizer::TYPE_SYMBOL , "%" , 0, 3 }, - { Tokenizer::TYPE_END , "" , 0, 4 }, + { Tokenizer::TYPE_SYMBOL , "!" , 0, 0, 1 }, + { Tokenizer::TYPE_SYMBOL , "@" , 0, 1, 2 }, + { Tokenizer::TYPE_SYMBOL , "+" , 0, 2, 3 }, + { Tokenizer::TYPE_SYMBOL , "%" , 0, 3, 4 }, + { Tokenizer::TYPE_END , "" , 0, 4, 4 }, }}, // Test that newlines affect line numbers correctly. { "foo bar\nrab oof", { - { Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0 }, - { Tokenizer::TYPE_IDENTIFIER, "bar", 0, 4 }, - { Tokenizer::TYPE_IDENTIFIER, "rab", 1, 0 }, - { Tokenizer::TYPE_IDENTIFIER, "oof", 1, 4 }, - { Tokenizer::TYPE_END , "" , 1, 7 }, + { Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0, 3 }, + { Tokenizer::TYPE_IDENTIFIER, "bar", 0, 4, 7 }, + { Tokenizer::TYPE_IDENTIFIER, "rab", 1, 0, 3 }, + { Tokenizer::TYPE_IDENTIFIER, "oof", 1, 4, 7 }, + { Tokenizer::TYPE_END , "" , 1, 7, 7 }, }}, // Test that tabs affect column numbers correctly. { "foo\tbar \tbaz", { - { Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0 }, - { Tokenizer::TYPE_IDENTIFIER, "bar", 0, 8 }, - { Tokenizer::TYPE_IDENTIFIER, "baz", 0, 16 }, - { Tokenizer::TYPE_END , "" , 0, 19 }, + { Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0, 3 }, + { Tokenizer::TYPE_IDENTIFIER, "bar", 0, 8, 11 }, + { Tokenizer::TYPE_IDENTIFIER, "baz", 0, 16, 19 }, + { Tokenizer::TYPE_END , "" , 0, 19, 19 }, + }}, + + // Test that tabs in string literals affect column numbers correctly. + { "\"foo\tbar\" baz", { + { Tokenizer::TYPE_STRING , "\"foo\tbar\"", 0, 0, 12 }, + { Tokenizer::TYPE_IDENTIFIER, "baz" , 0, 13, 16 }, + { Tokenizer::TYPE_END , "" , 0, 16, 16 }, }}, // Test that line comments are ignored. { "foo // This is a comment\n" "bar // This is another comment", { - { Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0 }, - { Tokenizer::TYPE_IDENTIFIER, "bar", 1, 0 }, - { Tokenizer::TYPE_END , "" , 1, 30 }, + { Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0, 3 }, + { Tokenizer::TYPE_IDENTIFIER, "bar", 1, 0, 3 }, + { Tokenizer::TYPE_END , "" , 1, 30, 30 }, }}, // Test that block comments are ignored. { "foo /* This is a block comment */ bar", { - { Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0 }, - { Tokenizer::TYPE_IDENTIFIER, "bar", 0, 34 }, - { Tokenizer::TYPE_END , "" , 0, 37 }, + { Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0, 3 }, + { Tokenizer::TYPE_IDENTIFIER, "bar", 0, 34, 37 }, + { Tokenizer::TYPE_END , "" , 0, 37, 37 }, }}, // Test that sh-style comments are not ignored by default. { "foo # bar\n" "baz", { - { Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0 }, - { Tokenizer::TYPE_SYMBOL , "#" , 0, 4 }, - { Tokenizer::TYPE_IDENTIFIER, "bar", 0, 6 }, - { Tokenizer::TYPE_IDENTIFIER, "baz", 1, 0 }, - { Tokenizer::TYPE_END , "" , 1, 3 }, + { Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0, 3 }, + { Tokenizer::TYPE_SYMBOL , "#" , 0, 4, 5 }, + { Tokenizer::TYPE_IDENTIFIER, "bar", 0, 6, 9 }, + { Tokenizer::TYPE_IDENTIFIER, "baz", 1, 0, 3 }, + { Tokenizer::TYPE_END , "" , 1, 3, 3 }, }}, // Bytes with the high-order bit set should not be seen as control characters. { "\300", { - { Tokenizer::TYPE_SYMBOL, "\300", 0, 0 }, - { Tokenizer::TYPE_END , "" , 0, 1 }, + { Tokenizer::TYPE_SYMBOL, "\300", 0, 0, 1 }, + { Tokenizer::TYPE_END , "" , 0, 1, 1 }, }}, // Test all whitespace chars { "foo\n\t\r\v\fbar", { - { Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0 }, - { Tokenizer::TYPE_IDENTIFIER, "bar", 1, 11 }, - { Tokenizer::TYPE_END , "" , 1, 14 }, + { Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0, 3 }, + { Tokenizer::TYPE_IDENTIFIER, "bar", 1, 11, 14 }, + { Tokenizer::TYPE_END , "" , 1, 14, 14 }, }}, }; @@ -425,6 +437,7 @@ TEST_2D(TokenizerTest, MultipleTokens, kMultiTokenCases, kBlockSizes) { EXPECT_EQ("", tokenizer.current().text); EXPECT_EQ(0, tokenizer.current().line); EXPECT_EQ(0, tokenizer.current().column); + EXPECT_EQ(0, tokenizer.current().end_column); // Loop through all expected tokens. int i = 0; @@ -434,6 +447,8 @@ TEST_2D(TokenizerTest, MultipleTokens, kMultiTokenCases, kBlockSizes) { SCOPED_TRACE(testing::Message() << "Token #" << i << ": " << token.text); + Tokenizer::Token previous = tokenizer.current(); + // Next() should only return false when it hits the end token. if (token.type != Tokenizer::TYPE_END) { ASSERT_TRUE(tokenizer.Next()); @@ -441,11 +456,19 @@ TEST_2D(TokenizerTest, MultipleTokens, kMultiTokenCases, kBlockSizes) { ASSERT_FALSE(tokenizer.Next()); } + // Check that the previous token is set correctly. + EXPECT_EQ(previous.type, tokenizer.previous().type); + EXPECT_EQ(previous.text, tokenizer.previous().text); + EXPECT_EQ(previous.line, tokenizer.previous().line); + EXPECT_EQ(previous.column, tokenizer.previous().column); + EXPECT_EQ(previous.end_column, tokenizer.previous().end_column); + // Check that the token matches the expected one. EXPECT_EQ(token.type, tokenizer.current().type); EXPECT_EQ(token.text, tokenizer.current().text); EXPECT_EQ(token.line, tokenizer.current().line); EXPECT_EQ(token.column, tokenizer.current().column); + EXPECT_EQ(token.end_column, tokenizer.current().end_column); } while (token.type != Tokenizer::TYPE_END); diff --git a/third_party/protobuf/src/google/protobuf/io/zero_copy_stream_unittest.cc b/third_party/protobuf/src/google/protobuf/io/zero_copy_stream_unittest.cc index 8229ee6..5196d90 100644 --- a/third_party/protobuf/src/google/protobuf/io/zero_copy_stream_unittest.cc +++ b/third_party/protobuf/src/google/protobuf/io/zero_copy_stream_unittest.cc @@ -61,6 +61,7 @@ #include <sstream> #include <google/protobuf/io/zero_copy_stream_impl.h> +#include <google/protobuf/io/coded_stream.h> #if HAVE_ZLIB #include <google/protobuf/io/gzip_stream.h> @@ -285,6 +286,57 @@ TEST_F(IoTest, ArrayIo) { } } +TEST_F(IoTest, TwoSessionWrite) { + // Test that two concatenated write sessions read correctly + + static const char* strA = "0123456789"; + static const char* strB = "WhirledPeas"; + const int kBufferSize = 2*1024; + uint8* buffer = new uint8[kBufferSize]; + char* temp_buffer = new char[40]; + + for (int i = 0; i < kBlockSizeCount; i++) { + for (int j = 0; j < kBlockSizeCount; j++) { + ArrayOutputStream* output = + new ArrayOutputStream(buffer, kBufferSize, kBlockSizes[i]); + CodedOutputStream* coded_output = new CodedOutputStream(output); + coded_output->WriteVarint32(strlen(strA)); + coded_output->WriteRaw(strA, strlen(strA)); + delete coded_output; // flush + int64 pos = output->ByteCount(); + delete output; + output = new ArrayOutputStream( + buffer + pos, kBufferSize - pos, kBlockSizes[i]); + coded_output = new CodedOutputStream(output); + coded_output->WriteVarint32(strlen(strB)); + coded_output->WriteRaw(strB, strlen(strB)); + delete coded_output; // flush + int64 size = pos + output->ByteCount(); + delete output; + + ArrayInputStream* input = + new ArrayInputStream(buffer, size, kBlockSizes[j]); + CodedInputStream* coded_input = new CodedInputStream(input); + uint32 insize; + EXPECT_TRUE(coded_input->ReadVarint32(&insize)); + EXPECT_EQ(strlen(strA), insize); + EXPECT_TRUE(coded_input->ReadRaw(temp_buffer, insize)); + EXPECT_EQ(0, memcmp(temp_buffer, strA, insize)); + + EXPECT_TRUE(coded_input->ReadVarint32(&insize)); + EXPECT_EQ(strlen(strB), insize); + EXPECT_TRUE(coded_input->ReadRaw(temp_buffer, insize)); + EXPECT_EQ(0, memcmp(temp_buffer, strB, insize)); + + delete coded_input; + delete input; + } + } + + delete [] temp_buffer; + delete [] buffer; +} + #if HAVE_ZLIB TEST_F(IoTest, GzipIo) { const int kBufferSize = 2*1024; @@ -296,8 +348,12 @@ TEST_F(IoTest, GzipIo) { int size; { ArrayOutputStream output(buffer, kBufferSize, kBlockSizes[i]); - GzipOutputStream gzout( - &output, GzipOutputStream::GZIP, gzip_buffer_size); + GzipOutputStream::Options options; + options.format = GzipOutputStream::GZIP; + if (gzip_buffer_size != -1) { + options.buffer_size = gzip_buffer_size; + } + GzipOutputStream gzout(&output, options); WriteStuff(&gzout); gzout.Close(); size = output.ByteCount(); @@ -324,8 +380,12 @@ TEST_F(IoTest, ZlibIo) { int size; { ArrayOutputStream output(buffer, kBufferSize, kBlockSizes[i]); - GzipOutputStream gzout( - &output, GzipOutputStream::ZLIB, gzip_buffer_size); + GzipOutputStream::Options options; + options.format = GzipOutputStream::ZLIB; + if (gzip_buffer_size != -1) { + options.buffer_size = gzip_buffer_size; + } + GzipOutputStream gzout(&output, options); WriteStuff(&gzout); gzout.Close(); size = output.ByteCount(); @@ -348,7 +408,9 @@ TEST_F(IoTest, ZlibIoInputAutodetect) { int size; { ArrayOutputStream output(buffer, kBufferSize); - GzipOutputStream gzout(&output, GzipOutputStream::ZLIB); + GzipOutputStream::Options options; + options.format = GzipOutputStream::ZLIB; + GzipOutputStream gzout(&output, options); WriteStuff(&gzout); gzout.Close(); size = output.ByteCount(); @@ -360,7 +422,9 @@ TEST_F(IoTest, ZlibIoInputAutodetect) { } { ArrayOutputStream output(buffer, kBufferSize); - GzipOutputStream gzout(&output, GzipOutputStream::GZIP); + GzipOutputStream::Options options; + options.format = GzipOutputStream::GZIP; + GzipOutputStream gzout(&output, options); WriteStuff(&gzout); gzout.Close(); size = output.ByteCount(); @@ -432,6 +496,71 @@ TEST_F(IoTest, CompressionOptions) { EXPECT_TRUE(Uncompress(gzip_compressed) == golden); EXPECT_TRUE(Uncompress(zlib_compressed) == golden); } + +TEST_F(IoTest, TwoSessionWriteGzip) { + // Test that two concatenated gzip streams can be read correctly + + static const char* strA = "0123456789"; + static const char* strB = "QuickBrownFox"; + const int kBufferSize = 2*1024; + uint8* buffer = new uint8[kBufferSize]; + char* temp_buffer = new char[40]; + + for (int i = 0; i < kBlockSizeCount; i++) { + for (int j = 0; j < kBlockSizeCount; j++) { + ArrayOutputStream* output = + new ArrayOutputStream(buffer, kBufferSize, kBlockSizes[i]); + GzipOutputStream* gzout = new GzipOutputStream(output); + CodedOutputStream* coded_output = new CodedOutputStream(gzout); + int32 outlen = strlen(strA) + 1; + coded_output->WriteVarint32(outlen); + coded_output->WriteRaw(strA, outlen); + delete coded_output; // flush + delete gzout; // flush + int64 pos = output->ByteCount(); + delete output; + output = new ArrayOutputStream( + buffer + pos, kBufferSize - pos, kBlockSizes[i]); + gzout = new GzipOutputStream(output); + coded_output = new CodedOutputStream(gzout); + outlen = strlen(strB) + 1; + coded_output->WriteVarint32(outlen); + coded_output->WriteRaw(strB, outlen); + delete coded_output; // flush + delete gzout; // flush + int64 size = pos + output->ByteCount(); + delete output; + + ArrayInputStream* input = + new ArrayInputStream(buffer, size, kBlockSizes[j]); + GzipInputStream* gzin = new GzipInputStream(input); + CodedInputStream* coded_input = new CodedInputStream(gzin); + uint32 insize; + EXPECT_TRUE(coded_input->ReadVarint32(&insize)); + EXPECT_EQ(strlen(strA) + 1, insize); + EXPECT_TRUE(coded_input->ReadRaw(temp_buffer, insize)); + EXPECT_EQ(0, memcmp(temp_buffer, strA, insize)) + << "strA=" << strA << " in=" << temp_buffer; + + EXPECT_TRUE(coded_input->ReadVarint32(&insize)); + EXPECT_EQ(strlen(strB) + 1, insize); + EXPECT_TRUE(coded_input->ReadRaw(temp_buffer, insize)); + EXPECT_EQ(0, memcmp(temp_buffer, strB, insize)) + << " out_block_size=" << kBlockSizes[i] + << " in_block_size=" << kBlockSizes[j] + << " pos=" << pos + << " size=" << size + << " strB=" << strB << " in=" << temp_buffer; + + delete coded_input; + delete gzin; + delete input; + } + } + + delete [] temp_buffer; + delete [] buffer; +} #endif // There is no string input, only string output. Also, it doesn't support diff --git a/third_party/protobuf/src/google/protobuf/message.h b/third_party/protobuf/src/google/protobuf/message.h index d117fe2..4bbc641 100644 --- a/third_party/protobuf/src/google/protobuf/message.h +++ b/third_party/protobuf/src/google/protobuf/message.h @@ -123,6 +123,7 @@ #include <google/protobuf/stubs/common.h> + namespace google { namespace protobuf { diff --git a/third_party/protobuf/src/google/protobuf/repeated_field.cc b/third_party/protobuf/src/google/protobuf/repeated_field.cc index f7beb11..0937774 100644 --- a/third_party/protobuf/src/google/protobuf/repeated_field.cc +++ b/third_party/protobuf/src/google/protobuf/repeated_field.cc @@ -32,11 +32,14 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. +#include <algorithm> + #include <google/protobuf/repeated_field.h> #include <google/protobuf/stubs/common.h> namespace google { namespace protobuf { + namespace internal { void RepeatedPtrFieldBase::Reserve(int new_size) { @@ -88,8 +91,8 @@ void StringTypeHandlerBase::Delete(string* value) { delete value; } +} // namespace internal -} // namespace internal } // namespace protobuf } // namespace google diff --git a/third_party/protobuf/src/google/protobuf/repeated_field.h b/third_party/protobuf/src/google/protobuf/repeated_field.h index cc07fdb..6080ddc 100644 --- a/third_party/protobuf/src/google/protobuf/repeated_field.h +++ b/third_party/protobuf/src/google/protobuf/repeated_field.h @@ -72,8 +72,11 @@ template <typename Element> class RepeatedField { public: RepeatedField(); + RepeatedField(const RepeatedField& other); ~RepeatedField(); + RepeatedField& operator=(const RepeatedField& other); + int size() const; const Element& Get(int index) const; @@ -90,6 +93,7 @@ class RepeatedField { void RemoveLast(); void Clear(); void MergeFrom(const RepeatedField& other); + void CopyFrom(const RepeatedField& other); // Reserve space to expand the field to at least the given size. If the // array is grown, it will always be at least doubled in size. @@ -116,6 +120,7 @@ class RepeatedField { // STL-like iterator support typedef Element* iterator; typedef const Element* const_iterator; + typedef Element value_type; iterator begin(); const_iterator begin() const; @@ -127,8 +132,6 @@ class RepeatedField { int SpaceUsedExcludingSelf() const; private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedField); - static const int kInitialSize = 4; Element* elements_; @@ -203,6 +206,8 @@ class LIBPROTOBUF_EXPORT RepeatedPtrFieldBase { void Clear(); template <typename TypeHandler> void MergeFrom(const RepeatedPtrFieldBase& other); + template <typename TypeHandler> + void CopyFrom(const RepeatedPtrFieldBase& other); void Reserve(int new_size); @@ -300,7 +305,7 @@ class LIBPROTOBUF_EXPORT StringTypeHandlerBase { static void Merge(const string& from, string* to) { *to = from; } }; -class StringTypeHandler : public StringTypeHandlerBase { +class LIBPROTOBUF_EXPORT StringTypeHandler : public StringTypeHandlerBase { public: static int SpaceUsed(const string& value) { return sizeof(value) + StringSpaceUsedExcludingSelf(value); @@ -316,9 +321,11 @@ template <typename Element> class RepeatedPtrField : public internal::RepeatedPtrFieldBase { public: RepeatedPtrField(); - + RepeatedPtrField(const RepeatedPtrField& other); ~RepeatedPtrField(); + RepeatedPtrField& operator=(const RepeatedPtrField& other); + int size() const; const Element& Get(int index) const; @@ -327,6 +334,7 @@ class RepeatedPtrField : public internal::RepeatedPtrFieldBase { void RemoveLast(); // Remove the last element in the array. void Clear(); void MergeFrom(const RepeatedPtrField& other); + void CopyFrom(const RepeatedPtrField& other); // Reserve space to expand the field to at least the given size. This only // resizes the pointer array; it doesn't allocate any objects. If the @@ -349,6 +357,7 @@ class RepeatedPtrField : public internal::RepeatedPtrFieldBase { // STL-like iterator support typedef internal::RepeatedPtrIterator<Element> iterator; typedef internal::RepeatedPtrIterator<const Element> const_iterator; + typedef Element value_type; iterator begin(); const_iterator begin() const; @@ -365,11 +374,6 @@ class RepeatedPtrField : public internal::RepeatedPtrFieldBase { // excluding sizeof(*this). int SpaceUsedExcludingSelf() const; - // The spaced used just by the pointer array, not counting the objects pointed - // at. Returns zero if the array is inlined (i.e. initial_space_ is being - // used). - int SpaceUsedByArray() const; - // Advanced memory management -------------------------------------- // When hardcore memory management becomes necessary -- as it often // does here at Google -- the following methods may be useful. @@ -410,9 +414,6 @@ class RepeatedPtrField : public internal::RepeatedPtrFieldBase { // methods on RepeatedPtrFieldBase. class TypeHandler; - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPtrField); }; // implementation ==================================================== @@ -425,6 +426,14 @@ inline RepeatedField<Element>::RepeatedField() } template <typename Element> +inline RepeatedField<Element>::RepeatedField(const RepeatedField& other) + : elements_(initial_space_), + current_size_(0), + total_size_(kInitialSize) { + CopyFrom(other); +} + +template <typename Element> RepeatedField<Element>::~RepeatedField() { if (elements_ != initial_space_) { delete [] elements_; @@ -432,6 +441,13 @@ RepeatedField<Element>::~RepeatedField() { } template <typename Element> +inline RepeatedField<Element>& +RepeatedField<Element>::operator=(const RepeatedField& other) { + CopyFrom(other); + return *this; +} + +template <typename Element> inline int RepeatedField<Element>::size() const { return current_size_; } @@ -502,6 +518,12 @@ inline void RepeatedField<Element>::MergeFrom(const RepeatedField& other) { } template <typename Element> +inline void RepeatedField<Element>::CopyFrom(const RepeatedField& other) { + Clear(); + MergeFrom(other); +} + +template <typename Element> inline Element* RepeatedField<Element>::mutable_data() { return elements_; } @@ -594,14 +616,14 @@ inline void RepeatedField<Element>::Truncate(int new_size) { template <typename Element> inline void RepeatedField<Element>::MoveArray( - Element to[], Element from[], int size) { - memcpy(to, from, size * sizeof(Element)); + Element to[], Element from[], int array_size) { + memcpy(to, from, array_size * sizeof(Element)); } template <typename Element> inline void RepeatedField<Element>::CopyArray( - Element to[], const Element from[], int size) { - memcpy(to, from, size * sizeof(Element)); + Element to[], const Element from[], int array_size) { + memcpy(to, from, array_size * sizeof(Element)); } @@ -679,6 +701,12 @@ inline void RepeatedPtrFieldBase::MergeFrom(const RepeatedPtrFieldBase& other) { } } +template <typename TypeHandler> +inline void RepeatedPtrFieldBase::CopyFrom(const RepeatedPtrFieldBase& other) { + RepeatedPtrFieldBase::Clear<TypeHandler>(); + RepeatedPtrFieldBase::MergeFrom<TypeHandler>(other); +} + inline int RepeatedPtrFieldBase::Capacity() const { return total_size_; } @@ -805,11 +833,24 @@ template <typename Element> inline RepeatedPtrField<Element>::RepeatedPtrField() {} template <typename Element> +inline RepeatedPtrField<Element>::RepeatedPtrField( + const RepeatedPtrField& other) { + CopyFrom(other); +} + +template <typename Element> RepeatedPtrField<Element>::~RepeatedPtrField() { Destroy<TypeHandler>(); } template <typename Element> +inline RepeatedPtrField<Element>& RepeatedPtrField<Element>::operator=( + const RepeatedPtrField& other) { + CopyFrom(other); + return *this; +} + +template <typename Element> inline int RepeatedPtrField<Element>::size() const { return RepeatedPtrFieldBase::size(); } @@ -846,6 +887,12 @@ inline void RepeatedPtrField<Element>::MergeFrom( } template <typename Element> +inline void RepeatedPtrField<Element>::CopyFrom( + const RepeatedPtrField& other) { + RepeatedPtrFieldBase::CopyFrom<TypeHandler>(other); +} + +template <typename Element> inline Element** RepeatedPtrField<Element>::mutable_data() { return RepeatedPtrFieldBase::mutable_data<TypeHandler>(); } @@ -944,7 +991,7 @@ class RepeatedPtrIterator template<typename OtherElement> RepeatedPtrIterator(const RepeatedPtrIterator<OtherElement>& other) : it_(other.it_) { - // Force a compiler error if the other type is not convertable to ours. + // Force a compiler error if the other type is not convertible to ours. if (false) { implicit_cast<Element*, OtherElement*>(0); } @@ -1152,7 +1199,7 @@ template<typename T> class RepeatedFieldBackInsertIterator } private: - RepeatedField<T>* const field_; + RepeatedField<T>* field_; }; // A back inserter for RepeatedPtrField objects. @@ -1183,7 +1230,7 @@ template<typename T> class RepeatedPtrFieldBackInsertIterator } private: - RepeatedPtrField<T>* const field_; + RepeatedPtrField<T>* field_; }; // A back inserter for RepeatedPtrFields that inserts by transfering ownership @@ -1212,7 +1259,7 @@ template<typename T> class AllocatedRepeatedPtrFieldBackInsertIterator } private: - RepeatedPtrField<T>* const field_; + RepeatedPtrField<T>* field_; }; } // namespace internal diff --git a/third_party/protobuf/src/google/protobuf/repeated_field_unittest.cc b/third_party/protobuf/src/google/protobuf/repeated_field_unittest.cc index 7c35f60..e7e1e99 100644 --- a/third_party/protobuf/src/google/protobuf/repeated_field_unittest.cc +++ b/third_party/protobuf/src/google/protobuf/repeated_field_unittest.cc @@ -232,6 +232,54 @@ TEST(RepeatedField, MergeFrom) { EXPECT_EQ(5, destination.Get(4)); } +TEST(RepeatedField, CopyFrom) { + RepeatedField<int> source, destination; + + source.Add(4); + source.Add(5); + + destination.Add(1); + destination.Add(2); + destination.Add(3); + + destination.CopyFrom(source); + + ASSERT_EQ(2, destination.size()); + + EXPECT_EQ(4, destination.Get(0)); + EXPECT_EQ(5, destination.Get(1)); +} + +TEST(RepeatedField, CopyConstruct) { + RepeatedField<int> source; + source.Add(1); + source.Add(2); + + RepeatedField<int> destination(source); + + ASSERT_EQ(2, destination.size()); + EXPECT_EQ(1, destination.Get(0)); + EXPECT_EQ(2, destination.Get(1)); +} + +TEST(RepeatedField, CopyAssign) { + RepeatedField<int> source, destination; + + source.Add(4); + source.Add(5); + + destination.Add(1); + destination.Add(2); + destination.Add(3); + + destination = source; + + ASSERT_EQ(2, destination.size()); + + EXPECT_EQ(4, destination.Get(0)); + EXPECT_EQ(5, destination.Get(1)); +} + TEST(RepeatedField, MutableDataIsMutable) { RepeatedField<int> field; field.Add(1); @@ -536,6 +584,55 @@ TEST(RepeatedPtrField, MergeFrom) { EXPECT_EQ("5", destination.Get(4)); } +TEST(RepeatedPtrField, CopyFrom) { + RepeatedPtrField<string> source, destination; + + source.Add()->assign("4"); + source.Add()->assign("5"); + + destination.Add()->assign("1"); + destination.Add()->assign("2"); + destination.Add()->assign("3"); + + destination.CopyFrom(source); + + ASSERT_EQ(2, destination.size()); + + EXPECT_EQ("4", destination.Get(0)); + EXPECT_EQ("5", destination.Get(1)); +} + +TEST(RepeatedPtrField, CopyConstruct) { + RepeatedPtrField<string> source; + + source.Add()->assign("1"); + source.Add()->assign("2"); + + RepeatedPtrField<string> destination(source); + + ASSERT_EQ(2, destination.size()); + EXPECT_EQ("1", destination.Get(0)); + EXPECT_EQ("2", destination.Get(1)); +} + +TEST(RepeatedPtrField, CopyAssign) { + RepeatedPtrField<string> source, destination; + + source.Add()->assign("4"); + source.Add()->assign("5"); + + destination.Add()->assign("1"); + destination.Add()->assign("2"); + destination.Add()->assign("3"); + + destination = source; + + ASSERT_EQ(2, destination.size()); + + EXPECT_EQ("4", destination.Get(0)); + EXPECT_EQ("5", destination.Get(1)); +} + TEST(RepeatedPtrField, MutableDataIsMutable) { RepeatedPtrField<string> field; *field.Add() = "1"; @@ -564,7 +661,8 @@ class RepeatedFieldIteratorTest : public testing::Test { TEST_F(RepeatedFieldIteratorTest, Convertible) { RepeatedField<int>::iterator iter = proto_array_.begin(); RepeatedField<int>::const_iterator c_iter = iter; - EXPECT_EQ(0, *c_iter); + RepeatedField<int>::value_type value = *c_iter; + EXPECT_EQ(0, value); } TEST_F(RepeatedFieldIteratorTest, MutableIteration) { @@ -613,6 +711,8 @@ class RepeatedPtrFieldIteratorTest : public testing::Test { TEST_F(RepeatedPtrFieldIteratorTest, Convertible) { RepeatedPtrField<string>::iterator iter = proto_array_.begin(); RepeatedPtrField<string>::const_iterator c_iter = iter; + RepeatedPtrField<string>::value_type value = *c_iter; + EXPECT_EQ("foo", value); } TEST_F(RepeatedPtrFieldIteratorTest, MutableIteration) { diff --git a/third_party/protobuf/src/google/protobuf/stubs/common.cc b/third_party/protobuf/src/google/protobuf/stubs/common.cc index 1e2d68d2..7b15be4 100644 --- a/third_party/protobuf/src/google/protobuf/stubs/common.cc +++ b/third_party/protobuf/src/google/protobuf/stubs/common.cc @@ -191,7 +191,11 @@ void LogMessage::Finish() { } if (level_ == LOGLEVEL_FATAL) { +#ifdef PROTOBUF_USE_EXCEPTIONS + throw FatalException(filename_, line_, message_); +#else abort(); +#endif } } @@ -361,5 +365,13 @@ void ShutdownProtobufLibrary() { internal::shutdown_functions_mutex = NULL; } +#ifdef PROTOBUF_USE_EXCEPTIONS +FatalException::~FatalException() throw() {} + +const char* FatalException::what() const throw() { + return message_.c_str(); +} +#endif + } // namespace protobuf } // namespace google diff --git a/third_party/protobuf/src/google/protobuf/stubs/common.h b/third_party/protobuf/src/google/protobuf/stubs/common.h index 2ffe035..bf3d3df 100644 --- a/third_party/protobuf/src/google/protobuf/stubs/common.h +++ b/third_party/protobuf/src/google/protobuf/stubs/common.h @@ -48,6 +48,15 @@ #include <stdint.h> #endif +#if defined(_MSC_VER) && defined(_CPPUNWIND) + #define PROTOBUF_USE_EXCEPTIONS +#elif defined(__EXCEPTIONS) + #define PROTOBUF_USE_EXCEPTIONS +#endif +#ifdef PROTOBUF_USE_EXCEPTIONS +#include <exception> +#endif + #if defined(_WIN32) && defined(GetMessage) // Allow GetMessage to be used as a valid method name in protobuf classes. // windows.h defines GetMessage() as a macro. Let's re-define it as an inline @@ -71,8 +80,6 @@ namespace std {} namespace google { namespace protobuf { -using namespace std; // Don't do this at home, kids. - #undef GOOGLE_DISALLOW_EVIL_CONSTRUCTORS #define GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TypeName) \ TypeName(const TypeName&); \ @@ -101,24 +108,24 @@ namespace internal { // The current version, represented as a single integer to make comparison // easier: major * 10^6 + minor * 10^3 + micro -#define GOOGLE_PROTOBUF_VERSION 2003001 +#define GOOGLE_PROTOBUF_VERSION 2004000 // The minimum library version which works with the current version of the // headers. -#define GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION 2003000 +#define GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION 2004000 // The minimum header version which works with the current version of // the library. This constant should only be used by protoc's C++ code // generator. -static const int kMinHeaderVersionForLibrary = 2003000; +static const int kMinHeaderVersionForLibrary = 2004000; // The minimum protoc version which works with the current version of the // headers. -#define GOOGLE_PROTOBUF_MIN_PROTOC_VERSION 2003000 +#define GOOGLE_PROTOBUF_MIN_PROTOC_VERSION 2004000 // The minimum header version which works with the current version of // protoc. This constant should only be used in VerifyVersion(). -static const int kMinHeaderVersionForProtoc = 2003000; +static const int kMinHeaderVersionForProtoc = 2004000; // Verifies that the headers and libraries are compatible. Use the macro // below to call this. @@ -126,7 +133,7 @@ void LIBPROTOBUF_EXPORT VerifyVersion(int headerVersion, int minLibraryVersion, const char* filename); // Converts a numeric version number to a string. -string LIBPROTOBUF_EXPORT VersionString(int version); +std::string LIBPROTOBUF_EXPORT VersionString(int version); } // namespace internal @@ -369,6 +376,7 @@ struct CompileAssert { typedef ::google::protobuf::internal::CompileAssert<(bool(expr))> \ msg[bool(expr) ? 1 : -1] + // Implementation details of COMPILE_ASSERT: // // - COMPILE_ASSERT works by defining an array type that has -1 @@ -636,7 +644,7 @@ class LIBPROTOBUF_EXPORT LogMessage { LogMessage(LogLevel level, const char* filename, int line); ~LogMessage(); - LogMessage& operator<<(const string& value); + LogMessage& operator<<(const std::string& value); LogMessage& operator<<(const char* value); LogMessage& operator<<(char value); LogMessage& operator<<(int value); @@ -652,7 +660,7 @@ class LIBPROTOBUF_EXPORT LogMessage { LogLevel level_; const char* filename_; int line_; - string message_; + std::string message_; }; // Used to make the entire "LOG(BLAH) << etc." expression have a void return @@ -731,7 +739,7 @@ class LIBPROTOBUF_EXPORT LogFinisher { #endif // !NDEBUG typedef void LogHandler(LogLevel level, const char* filename, int line, - const string& message); + const std::string& message); // The protobuf library sometimes writes warning and error messages to // stderr. These messages are primarily useful for developers, but may @@ -1173,6 +1181,30 @@ LIBPROTOBUF_EXPORT void OnShutdown(void (*func)()); } // namespace internal +#ifdef PROTOBUF_USE_EXCEPTIONS +class FatalException : public std::exception { + public: + FatalException(const char* filename, int line, const std::string& message) + : filename_(filename), line_(line), message_(message) {} + virtual ~FatalException() throw(); + + virtual const char* what() const throw(); + + const char* filename() const { return filename_; } + int line() const { return line_; } + const std::string& message() const { return message_; } + + private: + const char* filename_; + const int line_; + const std::string message_; +}; +#endif + +// This is at the end of the file instead of the beginning to work around a bug +// in some versions of MSVC. +using namespace std; // Don't do this at home, kids. + } // namespace protobuf } // namespace google diff --git a/third_party/protobuf/src/google/protobuf/text_format.cc b/third_party/protobuf/src/google/protobuf/text_format.cc index 137cbce..1494ebd 100644 --- a/third_party/protobuf/src/google/protobuf/text_format.cc +++ b/third_party/protobuf/src/google/protobuf/text_format.cc @@ -37,6 +37,7 @@ #include <stdio.h> #include <stack> #include <limits> +#include <vector> #include <google/protobuf/text_format.h> @@ -118,8 +119,10 @@ class TextFormat::Parser::ParserImpl { ParserImpl(const Descriptor* root_message_type, io::ZeroCopyInputStream* input_stream, io::ErrorCollector* error_collector, + TextFormat::Finder* finder, SingularOverwritePolicy singular_overwrite_policy) : error_collector_(error_collector), + finder_(finder), tokenizer_error_collector_(this), tokenizer_(input_stream, &tokenizer_error_collector_), root_message_type_(root_message_type), @@ -249,7 +252,9 @@ class TextFormat::Parser::ParserImpl { } DO(Consume("]")); - field = reflection->FindKnownExtensionByName(field_name); + field = (finder_ != NULL + ? finder_->FindExtension(message, field_name) + : reflection->FindKnownExtensionByName(field_name)); if (field == NULL) { ReportError("Extension \"" + field_name + "\" is not defined or " @@ -301,9 +306,24 @@ class TextFormat::Parser::ParserImpl { DO(ConsumeFieldMessage(message, reflection, field)); } else { DO(Consume(":")); - DO(ConsumeFieldValue(message, reflection, field)); + if (field->is_repeated() && TryConsume("[")) { + // Short repeated format, e.g. "foo: [1, 2, 3]" + while (true) { + DO(ConsumeFieldValue(message, reflection, field)); + if (TryConsume("]")) { + break; + } + DO(Consume(",")); + } + } else { + DO(ConsumeFieldValue(message, reflection, field)); + } } + // For historical reasons, fields may optionally be separated by commas or + // semicolons. + TryConsume(";") || TryConsume(","); + if (field->options().deprecated()) { ReportWarning("text format contains deprecated field \"" + field_name + "\""); @@ -397,29 +417,46 @@ class TextFormat::Parser::ParserImpl { } case FieldDescriptor::CPPTYPE_BOOL: { - string value; - DO(ConsumeIdentifier(&value)); - - if (value == "true") { - SET_FIELD(Bool, true); - } else if (value == "false") { - SET_FIELD(Bool, false); + if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) { + uint64 value; + DO(ConsumeUnsignedInteger(&value, 1)); + SET_FIELD(Bool, value); } else { - ReportError("Invalid value for boolean field \"" + field->name() - + "\". Value: \"" + value + "\"."); - return false; + string value; + DO(ConsumeIdentifier(&value)); + if (value == "true" || value == "t") { + SET_FIELD(Bool, true); + } else if (value == "false" || value == "f") { + SET_FIELD(Bool, false); + } else { + ReportError("Invalid value for boolean field \"" + field->name() + + "\". Value: \"" + value + "\"."); + return false; + } } break; } case FieldDescriptor::CPPTYPE_ENUM: { string value; - DO(ConsumeIdentifier(&value)); - - // Find the enumeration value. const EnumDescriptor* enum_type = field->enum_type(); - const EnumValueDescriptor* enum_value - = enum_type->FindValueByName(value); + const EnumValueDescriptor* enum_value = NULL; + + if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) { + DO(ConsumeIdentifier(&value)); + // Find the enumeration value. + enum_value = enum_type->FindValueByName(value); + + } else if (LookingAt("-") || + LookingAtType(io::Tokenizer::TYPE_INTEGER)) { + int64 int_value; + DO(ConsumeSignedInteger(&int_value, kint32max)); + value = SimpleItoa(int_value); // for error reporting + enum_value = enum_type->FindValueByNumber(int_value); + } else { + ReportError("Expected integer or identifier."); + return false; + } if (enum_value == NULL) { ReportError("Unknown enumeration value of \"" + value + "\" for " @@ -632,6 +669,7 @@ class TextFormat::Parser::ParserImpl { }; io::ErrorCollector* error_collector_; + TextFormat::Finder* finder_; ParserErrorCollector tokenizer_error_collector_; io::Tokenizer tokenizer_; const Descriptor* root_message_type_; @@ -765,9 +803,14 @@ class TextFormat::Printer::TextGenerator { // =========================================================================== +TextFormat::Finder::~Finder() { +} + TextFormat::Parser::Parser() : error_collector_(NULL), - allow_partial_(false) {} + finder_(NULL), + allow_partial_(false) { +} TextFormat::Parser::~Parser() {} @@ -775,7 +818,7 @@ bool TextFormat::Parser::Parse(io::ZeroCopyInputStream* input, Message* output) { output->Clear(); ParserImpl parser(output->GetDescriptor(), input, error_collector_, - ParserImpl::FORBID_SINGULAR_OVERWRITES); + finder_, ParserImpl::FORBID_SINGULAR_OVERWRITES); return MergeUsingImpl(input, output, &parser); } @@ -788,7 +831,7 @@ bool TextFormat::Parser::ParseFromString(const string& input, bool TextFormat::Parser::Merge(io::ZeroCopyInputStream* input, Message* output) { ParserImpl parser(output->GetDescriptor(), input, error_collector_, - ParserImpl::ALLOW_SINGULAR_OVERWRITES); + finder_, ParserImpl::ALLOW_SINGULAR_OVERWRITES); return MergeUsingImpl(input, output, &parser); } @@ -818,7 +861,7 @@ bool TextFormat::Parser::ParseFieldValueFromString( Message* output) { io::ArrayInputStream input_stream(input.data(), input.size()); ParserImpl parser(output->GetDescriptor(), &input_stream, error_collector_, - ParserImpl::ALLOW_SINGULAR_OVERWRITES); + finder_, ParserImpl::ALLOW_SINGULAR_OVERWRITES); return parser.ParseField(field, output); } @@ -853,7 +896,7 @@ TextFormat::Printer::Printer() TextFormat::Printer::~Printer() {} bool TextFormat::Printer::PrintToString(const Message& message, - string* output) { + string* output) const { GOOGLE_DCHECK(output) << "output specified is NULL"; output->clear(); @@ -866,7 +909,7 @@ bool TextFormat::Printer::PrintToString(const Message& message, bool TextFormat::Printer::PrintUnknownFieldsToString( const UnknownFieldSet& unknown_fields, - string* output) { + string* output) const { GOOGLE_DCHECK(output) << "output specified is NULL"; output->clear(); @@ -875,7 +918,7 @@ bool TextFormat::Printer::PrintUnknownFieldsToString( } bool TextFormat::Printer::Print(const Message& message, - io::ZeroCopyOutputStream* output) { + io::ZeroCopyOutputStream* output) const { TextGenerator generator(output, initial_indent_level_); Print(message, generator); @@ -886,7 +929,7 @@ bool TextFormat::Printer::Print(const Message& message, bool TextFormat::Printer::PrintUnknownFields( const UnknownFieldSet& unknown_fields, - io::ZeroCopyOutputStream* output) { + io::ZeroCopyOutputStream* output) const { TextGenerator generator(output, initial_indent_level_); PrintUnknownFields(unknown_fields, generator); @@ -896,7 +939,7 @@ bool TextFormat::Printer::PrintUnknownFields( } void TextFormat::Printer::Print(const Message& message, - TextGenerator& generator) { + TextGenerator& generator) const { const Reflection* reflection = message.GetReflection(); vector<const FieldDescriptor*> fields; reflection->ListFields(message, &fields); @@ -910,7 +953,7 @@ void TextFormat::Printer::PrintFieldValueToString( const Message& message, const FieldDescriptor* field, int index, - string* output) { + string* output) const { GOOGLE_DCHECK(output) << "output specified is NULL"; @@ -924,7 +967,7 @@ void TextFormat::Printer::PrintFieldValueToString( void TextFormat::Printer::PrintField(const Message& message, const Reflection* reflection, const FieldDescriptor* field, - TextGenerator& generator) { + TextGenerator& generator) const { if (use_short_repeated_primitives_ && field->is_repeated() && field->cpp_type() != FieldDescriptor::CPPTYPE_STRING && @@ -980,10 +1023,11 @@ void TextFormat::Printer::PrintField(const Message& message, } } -void TextFormat::Printer::PrintShortRepeatedField(const Message& message, - const Reflection* reflection, - const FieldDescriptor* field, - TextGenerator& generator) { +void TextFormat::Printer::PrintShortRepeatedField( + const Message& message, + const Reflection* reflection, + const FieldDescriptor* field, + TextGenerator& generator) const { // Print primitive repeated field in short form. PrintFieldName(message, reflection, field, generator); @@ -1003,7 +1047,7 @@ void TextFormat::Printer::PrintShortRepeatedField(const Message& message, void TextFormat::Printer::PrintFieldName(const Message& message, const Reflection* reflection, const FieldDescriptor* field, - TextGenerator& generator) { + TextGenerator& generator) const { if (field->is_extension()) { generator.Print("["); // We special-case MessageSet elements for compatibility with proto1. @@ -1031,7 +1075,7 @@ void TextFormat::Printer::PrintFieldValue( const Reflection* reflection, const FieldDescriptor* field, int index, - TextGenerator& generator) { + TextGenerator& generator) const { GOOGLE_DCHECK(field->is_repeated() || (index == -1)) << "Index must be -1 for non-repeated fields"; @@ -1143,7 +1187,7 @@ static string PaddedHex(IntType value) { } void TextFormat::Printer::PrintUnknownFields( - const UnknownFieldSet& unknown_fields, TextGenerator& generator) { + const UnknownFieldSet& unknown_fields, TextGenerator& generator) const { for (int i = 0; i < unknown_fields.field_count(); i++) { const UnknownField& field = unknown_fields.field(i); string field_number = SimpleItoa(field.number()); diff --git a/third_party/protobuf/src/google/protobuf/text_format.h b/third_party/protobuf/src/google/protobuf/text_format.h index e78e104..03c0491 100644 --- a/third_party/protobuf/src/google/protobuf/text_format.h +++ b/third_party/protobuf/src/google/protobuf/text_format.h @@ -90,20 +90,20 @@ class LIBPROTOBUF_EXPORT TextFormat { ~Printer(); // Like TextFormat::Print - bool Print(const Message& message, io::ZeroCopyOutputStream* output); + bool Print(const Message& message, io::ZeroCopyOutputStream* output) const; // Like TextFormat::PrintUnknownFields bool PrintUnknownFields(const UnknownFieldSet& unknown_fields, - io::ZeroCopyOutputStream* output); + io::ZeroCopyOutputStream* output) const; // Like TextFormat::PrintToString - bool PrintToString(const Message& message, string* output); + bool PrintToString(const Message& message, string* output) const; // Like TextFormat::PrintUnknownFieldsToString bool PrintUnknownFieldsToString(const UnknownFieldSet& unknown_fields, - string* output); + string* output) const; // Like TextFormat::PrintFieldValueToString void PrintFieldValueToString(const Message& message, const FieldDescriptor* field, int index, - string* output); + string* output) const; // Adjust the initial indent level of all output. Each indent level is // equal to two spaces. @@ -121,8 +121,7 @@ class LIBPROTOBUF_EXPORT TextFormat { // field_name: [1, 2, 3, 4] // instead of printing each value on its own line. Short format applies // only to primitive values -- i.e. everything except strings and - // sub-messages/groups. Note that at present this format is not recognized - // by the parser. + // sub-messages/groups. void SetUseShortRepeatedPrimitives(bool use_short_repeated_primitives) { use_short_repeated_primitives_ = use_short_repeated_primitives; } @@ -143,26 +142,26 @@ class LIBPROTOBUF_EXPORT TextFormat { // Internal Print method, used for writing to the OutputStream via // the TextGenerator class. void Print(const Message& message, - TextGenerator& generator); + TextGenerator& generator) const; // Print a single field. void PrintField(const Message& message, const Reflection* reflection, const FieldDescriptor* field, - TextGenerator& generator); + TextGenerator& generator) const; // Print a repeated primitive field in short form. void PrintShortRepeatedField(const Message& message, const Reflection* reflection, const FieldDescriptor* field, - TextGenerator& generator); + TextGenerator& generator) const; // Print the name of a field -- i.e. everything that comes before the // ':' for a single name/value pair. void PrintFieldName(const Message& message, const Reflection* reflection, const FieldDescriptor* field, - TextGenerator& generator); + TextGenerator& generator) const; // Outputs a textual representation of the value of the field supplied on // the message supplied or the default value if not set. @@ -170,13 +169,13 @@ class LIBPROTOBUF_EXPORT TextFormat { const Reflection* reflection, const FieldDescriptor* field, int index, - TextGenerator& generator); + TextGenerator& generator) const; // Print the fields in an UnknownFieldSet. They are printed by tag number // only. Embedded messages are heuristically identified by attempting to // parse them. void PrintUnknownFields(const UnknownFieldSet& unknown_fields, - TextGenerator& generator); + TextGenerator& generator) const; int initial_indent_level_; @@ -207,6 +206,20 @@ class LIBPROTOBUF_EXPORT TextFormat { const FieldDescriptor* field, Message* message); + // Interface that TextFormat::Parser can use to find extensions. + // This class may be extended in the future to find more information + // like fields, etc. + class LIBPROTOBUF_EXPORT Finder { + public: + virtual ~Finder(); + + // Try to find an extension of *message by fully-qualified field + // name. Returns NULL if no extension is known for this name or number. + virtual const FieldDescriptor* FindExtension( + Message* message, + const string& name) const = 0; + }; + // For more control over parsing, use this class. class LIBPROTOBUF_EXPORT Parser { public: @@ -228,6 +241,13 @@ class LIBPROTOBUF_EXPORT TextFormat { error_collector_ = error_collector; } + // Set how parser finds extensions. If NULL (the default), the + // parser will use the standard Reflection object associated with + // the message being parsed. + void SetFinder(Finder* finder) { + finder_ = finder; + } + // Normally parsing fails if, after parsing, output->IsInitialized() // returns false. Call AllowPartialMessage(true) to skip this check. void AllowPartialMessage(bool allow) { @@ -251,6 +271,7 @@ class LIBPROTOBUF_EXPORT TextFormat { ParserImpl* parser_impl); io::ErrorCollector* error_collector_; + Finder* finder_; bool allow_partial_; }; diff --git a/third_party/protobuf/src/google/protobuf/text_format_unittest.cc b/third_party/protobuf/src/google/protobuf/text_format_unittest.cc index ddf8ff7..00ea8c3 100644 --- a/third_party/protobuf/src/google/protobuf/text_format_unittest.cc +++ b/third_party/protobuf/src/google/protobuf/text_format_unittest.cc @@ -353,6 +353,25 @@ TEST_F(TextFormatExtensionsTest, ParseExtensions) { TestUtil::ExpectAllExtensionsSet(proto_); } +TEST_F(TextFormatTest, ParseEnumFieldFromNumber) { + // Create a parse string with a numerical value for an enum field. + string parse_string = strings::Substitute("optional_nested_enum: $0", + unittest::TestAllTypes::BAZ); + EXPECT_TRUE(TextFormat::ParseFromString(parse_string, &proto_)); + EXPECT_TRUE(proto_.has_optional_nested_enum()); + EXPECT_EQ(unittest::TestAllTypes::BAZ, proto_.optional_nested_enum()); +} + +TEST_F(TextFormatTest, ParseEnumFieldFromNegativeNumber) { + ASSERT_LT(unittest::SPARSE_E, 0); + string parse_string = strings::Substitute("sparse_enum: $0", + unittest::SPARSE_E); + unittest::SparseEnumMessage proto; + EXPECT_TRUE(TextFormat::ParseFromString(parse_string, &proto)); + EXPECT_TRUE(proto.has_sparse_enum()); + EXPECT_EQ(unittest::SPARSE_E, proto.sparse_enum()); +} + TEST_F(TextFormatTest, ParseStringEscape) { // Create a parse string with escpaed characters in it. string parse_string = "optional_string: " @@ -406,6 +425,34 @@ TEST_F(TextFormatTest, ParseFloatWithSuffix) { EXPECT_EQ(1.0, proto_.optional_float()); } +TEST_F(TextFormatTest, ParseShortRepeatedForm) { + string parse_string = + // Mixed short-form and long-form are simply concatenated. + "repeated_int32: 1\n" + "repeated_int32: [456, 789]\n" + "repeated_nested_enum: [ FOO ,BAR, # comment\n" + " 3]\n" + // Note that while the printer won't print repeated strings in short-form, + // the parser will accept them. + "repeated_string: [ \"foo\", 'bar' ]\n"; + + ASSERT_TRUE(TextFormat::ParseFromString(parse_string, &proto_)); + + ASSERT_EQ(3, proto_.repeated_int32_size()); + EXPECT_EQ(1, proto_.repeated_int32(0)); + EXPECT_EQ(456, proto_.repeated_int32(1)); + EXPECT_EQ(789, proto_.repeated_int32(2)); + + ASSERT_EQ(3, proto_.repeated_nested_enum_size()); + EXPECT_EQ(unittest::TestAllTypes::FOO, proto_.repeated_nested_enum(0)); + EXPECT_EQ(unittest::TestAllTypes::BAR, proto_.repeated_nested_enum(1)); + EXPECT_EQ(unittest::TestAllTypes::BAZ, proto_.repeated_nested_enum(2)); + + ASSERT_EQ(2, proto_.repeated_string_size()); + EXPECT_EQ("foo", proto_.repeated_string(0)); + EXPECT_EQ("bar", proto_.repeated_string(1)); +} + TEST_F(TextFormatTest, Comments) { // Test that comments are ignored. @@ -771,7 +818,12 @@ TEST_F(TextFormatParserTest, ParseFieldValueFromString) { // bool EXPECT_FIELD(bool, true, "true"); EXPECT_FIELD(bool, false, "false"); - EXPECT_INVALID(bool, "1"); + EXPECT_FIELD(bool, true, "1"); + EXPECT_FIELD(bool, true, "t"); + EXPECT_FIELD(bool, false, "0"); + EXPECT_FIELD(bool, false, "f"); + EXPECT_INVALID(bool, "2"); + EXPECT_INVALID(bool, "-0"); EXPECT_INVALID(bool, "on"); EXPECT_INVALID(bool, "a"); EXPECT_INVALID(bool, "True"); @@ -799,7 +851,8 @@ TEST_F(TextFormatParserTest, ParseFieldValueFromString) { // enum EXPECT_FIELD(nested_enum, unittest::TestAllTypes::BAR, "BAR"); - EXPECT_INVALID(nested_enum, "1"); // number not supported + EXPECT_FIELD(nested_enum, unittest::TestAllTypes::BAZ, + SimpleItoa(unittest::TestAllTypes::BAZ)); EXPECT_INVALID(nested_enum, "FOOBAR"); // message @@ -820,7 +873,7 @@ TEST_F(TextFormatParserTest, InvalidToken) { ExpectFailure("optional_bool: true\n-5\n", "Expected identifier.", 2, 1); - ExpectFailure("optional_bool: true;\n", "Expected identifier.", 1, 20); + ExpectFailure("optional_bool: true!\n", "Expected identifier.", 1, 20); ExpectFailure("\"some string\"", "Expected identifier.", 1, 1); } @@ -890,7 +943,7 @@ TEST_F(TextFormatParserTest, InvalidFieldValues) { // Invalid values for a boolean field. ExpectFailure("optional_bool: \"hello\"\n", "Expected identifier.", 1, 16); - ExpectFailure("optional_bool: 5\n", "Expected identifier.", 1, 16); + ExpectFailure("optional_bool: 5\n", "Integer out of range.", 1, 16); ExpectFailure("optional_bool: -7.5\n", "Expected identifier.", 1, 16); ExpectFailure("optional_bool: !\n", "Expected identifier.", 1, 16); @@ -911,12 +964,18 @@ TEST_F(TextFormatParserTest, InvalidFieldValues) { 1, 17); // Invalid values for an enumeration field. - ExpectFailure("optional_nested_enum: \"hello\"\n", "Expected identifier.", - 1, 23); - - ExpectFailure("optional_nested_enum: 5\n", "Expected identifier.", 1, 23); - ExpectFailure("optional_nested_enum: -7.5\n", "Expected identifier.", 1, 23); - ExpectFailure("optional_nested_enum: !\n", "Expected identifier.", 1, 23); + ExpectFailure("optional_nested_enum: \"hello\"\n", + "Expected integer or identifier.", 1, 23); + + // Valid token, but enum value is not defined. + ExpectFailure("optional_nested_enum: 5\n", + "Unknown enumeration value of \"5\" for field " + "\"optional_nested_enum\".", 2, 1); + // We consume the negative sign, so the error position starts one character + // later. + ExpectFailure("optional_nested_enum: -7.5\n", "Expected integer.", 1, 24); + ExpectFailure("optional_nested_enum: !\n", + "Expected integer or identifier.", 1, 23); ExpectFailure( "optional_nested_enum: grah\n", @@ -986,6 +1045,14 @@ TEST_F(TextFormatParserTest, MergeDuplicateOptional) { EXPECT_EQ(2, message.c()); } +TEST_F(TextFormatParserTest, ExplicitDelimiters) { + unittest::TestRequired message; + EXPECT_TRUE(TextFormat::ParseFromString("a:1,b:2;c:3", &message)); + EXPECT_EQ(1, message.a()); + EXPECT_EQ(2, message.b()); + EXPECT_EQ(3, message.c()); +} + TEST_F(TextFormatParserTest, PrintErrorsToStderr) { vector<string> errors; diff --git a/third_party/protobuf/src/google/protobuf/unittest.proto b/third_party/protobuf/src/google/protobuf/unittest.proto index d51fa1e..97ec674 100644 --- a/third_party/protobuf/src/google/protobuf/unittest.proto +++ b/third_party/protobuf/src/google/protobuf/unittest.proto @@ -35,6 +35,12 @@ // A proto file we will use for unit testing. +// Some generic_services option(s) added automatically. +// See: http://go/proto2-generic-services-default +option cc_generic_services = true; // auto-added +option java_generic_services = true; // auto-added +option py_generic_services = true; // auto-added + import "google/protobuf/unittest_import.proto"; // We don't put this in a package within proto2 because we need to make sure @@ -487,6 +493,17 @@ message TestExtremeDefaultValues { optional float inf_float = 17 [default = inf]; optional float neg_inf_float = 18 [default = -inf]; optional float nan_float = 19 [default = nan]; + + // Tests for C++ trigraphs. + // Trigraphs should be escaped in C++ generated files, but they should not be + // escaped for other languages. + // Note that in .proto file, "\?" is a valid way to escape ? in string + // literals. + optional string cpp_trigraph = 20 [default = "? \? ?? \?? \??? ??/ ?\?-"]; +} + +message SparseEnumMessage { + optional TestSparseEnum sparse_enum = 1; } // Test String and Bytes: string is for valid UTF-8 strings @@ -598,6 +615,7 @@ message TestRepeatedScalarDifferentTagSizes { repeated uint64 repeated_uint64 = 262143; } + // Test that RPC services work. message FooRequest {} message FooResponse {} diff --git a/third_party/protobuf/src/google/protobuf/unittest_custom_options.proto b/third_party/protobuf/src/google/protobuf/unittest_custom_options.proto index b6ee03d..a610785 100644 --- a/third_party/protobuf/src/google/protobuf/unittest_custom_options.proto +++ b/third_party/protobuf/src/google/protobuf/unittest_custom_options.proto @@ -35,6 +35,12 @@ // A proto file used to test the "custom options" feature of proto2. +// Some generic_services option(s) added automatically. +// See: http://go/proto2-generic-services-default +option cc_generic_services = true; // auto-added +option java_generic_services = true; // auto-added +option py_generic_services = true; + // A custom file option (defined below). option (file_opt1) = 9876543210; @@ -273,3 +279,88 @@ message VariousComplexOptions { option (complex_opt3).complexoptiontype5.plugh = 22; option (complexopt6).xyzzy = 24; } + +// ------------------------------------------------------ +// Definitions for testing aggregate option parsing. +// See descriptor_unittest.cc. + +message AggregateMessageSet { + option message_set_wire_format = true; + extensions 4 to max; +} + +message AggregateMessageSetElement { + extend AggregateMessageSet { + optional AggregateMessageSetElement message_set_extension = 15447542; + } + optional string s = 1; +} + +// A helper type used to test aggregate option parsing +message Aggregate { + optional int32 i = 1; + optional string s = 2; + + // A nested object + optional Aggregate sub = 3; + + // To test the parsing of extensions inside aggregate values + optional google.protobuf.FileOptions file = 4; + extend google.protobuf.FileOptions { + optional Aggregate nested = 15476903; + } + + // An embedded message set + optional AggregateMessageSet mset = 5; +} + +// Allow Aggregate to be used as an option at all possible locations +// in the .proto grammer. +extend google.protobuf.FileOptions { optional Aggregate fileopt = 15478479; } +extend google.protobuf.MessageOptions { optional Aggregate msgopt = 15480088; } +extend google.protobuf.FieldOptions { optional Aggregate fieldopt = 15481374; } +extend google.protobuf.EnumOptions { optional Aggregate enumopt = 15483218; } +extend google.protobuf.EnumValueOptions { optional Aggregate enumvalopt = 15486921; } +extend google.protobuf.ServiceOptions { optional Aggregate serviceopt = 15497145; } +extend google.protobuf.MethodOptions { optional Aggregate methodopt = 15512713; } + +// Try using AggregateOption at different points in the proto grammar +option (fileopt) = { + s: 'FileAnnotation' + // Also test the handling of comments + /* of both types */ i: 100 + + sub { s: 'NestedFileAnnotation' } + + // Include a google.protobuf.FileOptions and recursively extend it with + // another fileopt. + file { + [protobuf_unittest.fileopt] { + s:'FileExtensionAnnotation' + } + } + + // A message set inside an option value + mset { + [protobuf_unittest.AggregateMessageSetElement.message_set_extension] { + s: 'EmbeddedMessageSetElement' + } + } +}; + +message AggregateMessage { + option (msgopt) = { i:101 s:'MessageAnnotation' }; + optional int32 fieldname = 1 [(fieldopt) = { s:'FieldAnnotation' }]; +} + +service AggregateService { + option (serviceopt) = { s:'ServiceAnnotation' }; + rpc Method (AggregateMessage) returns (AggregateMessage) { + option (methodopt) = { s:'MethodAnnotation' }; + } +} + +enum AggregateEnum { + option (enumopt) = { s:'EnumAnnotation' }; + VALUE = 1 [(enumvalopt) = { s:'EnumValueAnnotation' }]; +} diff --git a/third_party/protobuf/src/google/protobuf/unittest_no_generic_services.proto b/third_party/protobuf/src/google/protobuf/unittest_no_generic_services.proto index fcae421..cffb412 100644 --- a/third_party/protobuf/src/google/protobuf/unittest_no_generic_services.proto +++ b/third_party/protobuf/src/google/protobuf/unittest_no_generic_services.proto @@ -32,9 +32,7 @@ package google.protobuf.no_generic_services_test; -option cc_generic_services = false; -option java_generic_services = false; -option py_generic_services = false; +// *_generic_services are false by default. message TestMessage { optional int32 a = 1; diff --git a/third_party/protobuf/src/google/protobuf/wire_format_lite_inl.h b/third_party/protobuf/src/google/protobuf/wire_format_lite_inl.h index d7b2c30..103b0bd 100644 --- a/third_party/protobuf/src/google/protobuf/wire_format_lite_inl.h +++ b/third_party/protobuf/src/google/protobuf/wire_format_lite_inl.h @@ -222,7 +222,7 @@ inline const uint8* WireFormatLite::ReadPrimitiveFromArray< } template <typename CType, enum WireFormatLite::FieldType DeclaredType> -inline bool WireFormatLite::ReadRepeatedPrimitive(int tag_size, +inline bool WireFormatLite::ReadRepeatedPrimitive(int, // tag_size, unused. uint32 tag, io::CodedInputStream* input, RepeatedField<CType>* values) { @@ -368,12 +368,24 @@ inline bool WireFormatLite::ReadMessage(io::CodedInputStream* input, return true; } -template<typename MessageType> -inline bool WireFormatLite::ReadGroupNoVirtual(int field_number, - io::CodedInputStream* input, - MessageType* value) { +// We name the template parameter something long and extremely unlikely to occur +// elsewhere because a *qualified* member access expression designed to avoid +// virtual dispatch, C++03 [basic.lookup.classref] 3.4.5/4 requires that the +// name of the qualifying class to be looked up both in the context of the full +// expression (finding the template parameter) and in the context of the object +// whose member we are accessing. This could potentially find a nested type +// within that object. The standard goes on to require these names to refer to +// the same entity, which this collision would violate. The lack of a safe way +// to avoid this collision appears to be a defect in the standard, but until it +// is corrected, we choose the name to avoid accidental collisions. +template<typename MessageType_WorkAroundCppLookupDefect> +inline bool WireFormatLite::ReadGroupNoVirtual( + int field_number, io::CodedInputStream* input, + MessageType_WorkAroundCppLookupDefect* value) { if (!input->IncrementRecursionDepth()) return false; - if (!value->MessageType::MergePartialFromCodedStream(input)) return false; + if (!value-> + MessageType_WorkAroundCppLookupDefect::MergePartialFromCodedStream(input)) + return false; input->DecrementRecursionDepth(); // Make sure the last thing read was an end tag for this group. if (!input->LastTagWas(MakeTag(field_number, WIRETYPE_END_GROUP))) { @@ -381,14 +393,16 @@ inline bool WireFormatLite::ReadGroupNoVirtual(int field_number, } return true; } -template<typename MessageType> -inline bool WireFormatLite::ReadMessageNoVirtual(io::CodedInputStream* input, - MessageType* value) { +template<typename MessageType_WorkAroundCppLookupDefect> +inline bool WireFormatLite::ReadMessageNoVirtual( + io::CodedInputStream* input, MessageType_WorkAroundCppLookupDefect* value) { uint32 length; if (!input->ReadVarint32(&length)) return false; if (!input->IncrementRecursionDepth()) return false; io::CodedInputStream::Limit limit = input->PushLimit(length); - if (!value->MessageType::MergePartialFromCodedStream(input)) return false; + if (!value-> + MessageType_WorkAroundCppLookupDefect::MergePartialFromCodedStream(input)) + return false; // Make sure that parsing stopped when the limit was hit, not at an endgroup // tag. if (!input->ConsumedEntireMessage()) return false; @@ -461,21 +475,24 @@ inline void WireFormatLite::WriteEnumNoTag(int value, output->WriteVarint32SignExtended(value); } -template<typename MessageType> -inline void WireFormatLite::WriteGroupNoVirtual(int field_number, - const MessageType& value, - io::CodedOutputStream* output) { +// See comment on ReadGroupNoVirtual to understand the need for this template +// parameter name. +template<typename MessageType_WorkAroundCppLookupDefect> +inline void WireFormatLite::WriteGroupNoVirtual( + int field_number, const MessageType_WorkAroundCppLookupDefect& value, + io::CodedOutputStream* output) { WriteTag(field_number, WIRETYPE_START_GROUP, output); - value.MessageType::SerializeWithCachedSizes(output); + value.MessageType_WorkAroundCppLookupDefect::SerializeWithCachedSizes(output); WriteTag(field_number, WIRETYPE_END_GROUP, output); } -template<typename MessageType> -inline void WireFormatLite::WriteMessageNoVirtual(int field_number, - const MessageType& value, - io::CodedOutputStream* output) { +template<typename MessageType_WorkAroundCppLookupDefect> +inline void WireFormatLite::WriteMessageNoVirtual( + int field_number, const MessageType_WorkAroundCppLookupDefect& value, + io::CodedOutputStream* output) { WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output); - output->WriteVarint32(value.MessageType::GetCachedSize()); - value.MessageType::SerializeWithCachedSizes(output); + output->WriteVarint32( + value.MessageType_WorkAroundCppLookupDefect::GetCachedSize()); + value.MessageType_WorkAroundCppLookupDefect::SerializeWithCachedSizes(output); } // =================================================================== @@ -672,20 +689,26 @@ inline uint8* WireFormatLite::WriteMessageToArray(int field_number, return value.SerializeWithCachedSizesToArray(target); } -template<typename MessageType> +// See comment on ReadGroupNoVirtual to understand the need for this template +// parameter name. +template<typename MessageType_WorkAroundCppLookupDefect> inline uint8* WireFormatLite::WriteGroupNoVirtualToArray( - int field_number, const MessageType& value, uint8* target) { + int field_number, const MessageType_WorkAroundCppLookupDefect& value, + uint8* target) { target = WriteTagToArray(field_number, WIRETYPE_START_GROUP, target); - target = value.MessageType::SerializeWithCachedSizesToArray(target); + target = value.MessageType_WorkAroundCppLookupDefect + ::SerializeWithCachedSizesToArray(target); return WriteTagToArray(field_number, WIRETYPE_END_GROUP, target); } -template<typename MessageType> +template<typename MessageType_WorkAroundCppLookupDefect> inline uint8* WireFormatLite::WriteMessageNoVirtualToArray( - int field_number, const MessageType& value, uint8* target) { + int field_number, const MessageType_WorkAroundCppLookupDefect& value, + uint8* target) { target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target); target = io::CodedOutputStream::WriteVarint32ToArray( - value.MessageType::GetCachedSize(), target); - return value.MessageType::SerializeWithCachedSizesToArray(target); + value.MessageType_WorkAroundCppLookupDefect::GetCachedSize(), target); + return value.MessageType_WorkAroundCppLookupDefect + ::SerializeWithCachedSizesToArray(target); } // =================================================================== @@ -730,13 +753,17 @@ inline int WireFormatLite::MessageSize(const MessageLite& value) { return io::CodedOutputStream::VarintSize32(size) + size; } -template<typename MessageType> -inline int WireFormatLite::GroupSizeNoVirtual(const MessageType& value) { - return value.MessageType::ByteSize(); +// See comment on ReadGroupNoVirtual to understand the need for this template +// parameter name. +template<typename MessageType_WorkAroundCppLookupDefect> +inline int WireFormatLite::GroupSizeNoVirtual( + const MessageType_WorkAroundCppLookupDefect& value) { + return value.MessageType_WorkAroundCppLookupDefect::ByteSize(); } -template<typename MessageType> -inline int WireFormatLite::MessageSizeNoVirtual(const MessageType& value) { - int size = value.MessageType::ByteSize(); +template<typename MessageType_WorkAroundCppLookupDefect> +inline int WireFormatLite::MessageSizeNoVirtual( + const MessageType_WorkAroundCppLookupDefect& value) { + int size = value.MessageType_WorkAroundCppLookupDefect::ByteSize(); return io::CodedOutputStream::VarintSize32(size) + size; } |