2015-05-25 version 3.0.0-alpha-3 (Objective-C/C#):
  General
  * Introduced two new language implementations (Objective-C, C#) to proto3.
  * Explicit "optional" keyword are disallowed in proto3 syntax, as fields are
    optional by default.
  * Group fields are no longer supported in proto3 syntax.
  * Changed repeated primitive fields to use packed serialization by default in
    proto3 (implemented for C++, Java, Python in this release).  The user can
    still disable packed serialization by setting packed to false for now.
  * Added well-known type protos (any.proto, empty.proto, timestamp.proto,
    duration.proto, etc.). Users can import and use these protos just like
    regular proto files. Addtional runtime support will be added for them in
    future releases (in the form of utility helper functions, or having them
    replaced by language specific types in generated code).
  * Added a "reserved" keyword in both proto2 and proto3 syntax. User can use
    this keyword to declare reserved field numbers and names to prevent them
    from being reused by other fields in the same message.

    To reserve field numbers, add a reserved declaration in your message:

      message TestMessage {
        reserved 2, 15, 9 to 11, 3;
      }

    This reserves field numbers 2, 3, 9, 10, 11 and 15. If a user uses any of
    these as field numbers, the protocol buffer compiler will report an error.

    Field names can also be reserved:

      message TestMessage {
        reserved "foo", "bar";
      }

  * Various bug fixes since 3.0.0-alpha-2

  Objective-C
    Objective-C includes a code generator and a native objective-c runtime
    library.  By adding “--objc_out” to protoc, the code generator will generate
    a header(*.pbobjc.h) and an implementation file(*.pbobjc.m) for each proto
    file.

    In this first release, the generated interface provides: enums, messages,
    field support(single, repeated, map, oneof), proto2 and proto3 syntax
    support, parsing and serialization. It’s  compatible with ARC and non-ARC
    usage. Besides, user can also access it via the swift bridging header.

    See objectivec/README.md for details.

  C#
    * C# protobufs are based on project
      https://github.com/jskeet/protobuf-csharp-port. The original project was
      frozen and all the new development will happen here.
    * Codegen plugin for C# was completely rewritten to C++ and is now an
      intergral part of protoc.
    * Some refactorings and cleanup has been applied to the C# runtime library.
    * Only proto2 is supported in C# at the moment, proto3 support is in
      progress and will likely bring significant breaking changes to the API.

    See csharp/README.md for details.

  C++
    * Added runtime support for Any type. To use Any in your proto file, first
      import the definition of Any:

        // foo.proto
        import "google/protobuf/any.proto";
        message Foo {
          google.protobuf.Any any_field = 1;
        }
        message Bar {
          int32 value = 1;
        }

      Then in C++ you can access the Any field using PackFrom()/UnpackTo()
      methods:

        Foo foo;
        Bar bar = ...;
        foo.mutable_any_field()->PackFrom(bar);
        ...
        if (foo.any_field().IsType<Bar>()) {
          foo.any_field().UnpackTo(&bar);
          ...
        }
    * In text format, entries of a map field will be sorted by key.

  Java
    * Continued optimizations on the lite runtime to improve performance for
      Android.

  Python
    * Added map support.
      - maps now have a dict-like interface (msg.map_field[key] = value)
      - existing code that modifies maps via the repeated field interface
        will need to be updated.

  Ruby
    * Improvements to RepeatedField's emulation of the Ruby Array API.
    * Various speedups and internal cleanups.

2015-02-26 version 3.0.0-alpha-2 (Python/Ruby/JavaNano):
  General
  * Introduced three new language implementations (Ruby, JavaNano, and
    Python) to proto3.
  * Various bug fixes since 3.0.0-alpha-1

  Python:
    Python has received several updates, most notably support for proto3
    semantics in any .proto file that declares syntax="proto3".
    Messages declared in proto3 files no longer represent field presence
    for scalar fields (number, enums, booleans, or strings).  You can
    no longer call HasField() for such fields, and they are serialized
    based on whether they have a non-zero/empty/false value.

    One other notable change is in the C++-accelerated implementation.
    Descriptor objects (which describe the protobuf schema and allow
    reflection over it) are no longer duplicated between the Python
    and C++ layers.  The Python descriptors are now simple wrappers
    around the C++ descriptors.  This change should significantly
    reduce the memory usage of programs that use a lot of message
    types.

  Ruby:
    We have added proto3 support for Ruby via a native C extension.

    The Ruby extension itself is included in the ruby/ directory, and details on
    building and installing the extension are in ruby/README.md. The extension
    will also be published as a Ruby gem. Code generator support is included as
    part of `protoc` with the `--ruby_out` flag.

    The Ruby extension implements a user-friendly DSL to define message types
    (also generated by the code generator from `.proto` files).  Once a message
    type is defined, the user may create instances of the message that behave in
    ways idiomatic to Ruby. For example:

    - Message fields are present as ordinary Ruby properties (getter method
      `foo` and setter method `foo=`).
    - Repeated field elements are stored in a container that acts like a native
      Ruby array, and map elements are stored in a container that acts like a
      native Ruby hashmap.
    - The usual well-known methods, such as `#to_s`, `#dup`, and the like, are
      present.

    Unlike several existing third-party Ruby extensions for protobuf, this
    extension is built on a "strongly-typed" philosophy: message fields and
    array/map containers will throw exceptions eagerly when values of the
    incorrect type are inserted.

    See ruby/README.md for details.

  JavaNano:
    JavaNano is a special code generator and runtime library designed especially
    for resource-restricted systems, like Android. It is very resource-friendly
    in both the amount of code and the runtime overhead. Here is an an overview
    of JavaNano features compared with the official Java protobuf:

    - No descriptors or message builders.
    - All messages are mutable; fields are public Java fields.
    - For optional fields only, encapsulation behind setter/getter/hazzer/
      clearer functions is opt-in, which provide proper 'has' state support.
    - For proto2, if not opted in, has state (field presence) is not available.
      Serialization outputs all fields not equal to their defaults.
      The behavior is consistent with proto3 semantics.
    - Required fields (proto2 only) are always serialized.
    - Enum constants are integers; protection against invalid values only
      when parsing from the wire.
    - Enum constants can be generated into container interfaces bearing
      the enum's name (so the referencing code is in Java style).
    - CodedInputByteBufferNano can only take byte[] (not InputStream).
    - Similarly CodedOutputByteBufferNano can only write to byte[].
    - Repeated fields are in arrays, not ArrayList or Vector. Null array
      elements are allowed and silently ignored.
    - Full support for serializing/deserializing repeated packed fields.
    - Support  extensions (in proto2).
    - Unset messages/groups are null, not an immutable empty default
      instance.
    - toByteArray(...) and mergeFrom(...) are now static functions of
      MessageNano.
    - The 'bytes' type translates to the Java type byte[].

    See javanano/README.txt for details.

2014-12-01 version 3.0.0-alpha-1 (C++/Java):

  General
  * Introduced Protocol Buffers language version 3 (aka proto3).

    When protobuf was initially opensourced it implemented Protocol Buffers
    language version 2 (aka proto2), which is why the version number
    started from v2.0.0. From v3.0.0, a new language version (proto3) is
    introduced while the old version (proto2) will continue to be supported.

    The main intent of introducing proto3 is to clean up protobuf before
    pushing the language as the foundation of Google's new API platform.
    In proto3, the language is simplified, both for ease of use and  to
    make it available in a wider range of programming languages. At the
    same time a few features are added to better support common idioms
    found in APIs.

    The following are the main new features in language version 3:

      1. Removal of field presence logic for primitive value fields, removal
         of required fields, and removal of default values. This makes proto3
         significantly easier to implement with open struct representations,
         as in languages like Android Java, Objective C, or Go.
      2. Removal of unknown fields.
      3. Removal of extensions, which are instead replaced by a new standard
         type called Any.
      4. Fix semantics for unknown enum values.
      5. Addition of maps.
      6. Addition of a small set of standard types for representation of time,
         dynamic data, etc.
      7. A well-defined encoding in JSON as an alternative to binary proto
         encoding.

    This release (v3.0.0-alpha-1) includes partial proto3 support for C++ and
    Java. Items 6 (well-known types) and 7 (JSON format) in the above feature
    list are not impelmented.

    A new notion "syntax" is introduced to specify whether a .proto file
    uses proto2 or proto3:

      // foo.proto
      syntax = "proto3";
      message Bar {...}

    If omitted, the protocol compiler will generate a warning and "proto2" will
    be used as the default. This warning will be turned into an error in a
    future release.

    We recommend that new Protocol Buffers users use proto3. However, we do not
    generally recommend that existing users migrate from proto2 from proto3 due
    to API incompatibility, and we will continue to support proto2 for a long
    time.

  * Added support for map fields (implemented in C++/Java for both proto2 and
    proto3).

    Map fields can be declared using the following syntax:

      message Foo {
        map<string, string> values = 1;
      }

    Data of a map field will be stored in memory as an unordered map and it
    can be accessed through generated accessors.

  C++
  * Added arena allocation support (for both proto2 and proto3).

    Profiling shows memory allocation and deallocation constitutes a significant
    fraction of CPU-time spent in protobuf code and arena allocation is a
    technique introduced to reduce this cost. With arena allocation, new
    objects will be allocated from a large piece of preallocated memory and
    deallocation of these objects is almost free. Early adoption shows 20% to
    50% improvement in some Google binaries.

    To enable arena support, add the following option to your .proto file:

      option cc_enable_arenas = true;

    Protocol compiler will generate additional code to make the generated
    message classes work with arenas. This does not change the existing API
    of protobuf messages and does not affect wire format. Your existing code
    should continue to work after adding this option. In the future we will
    make this option enabled by default.

    To actually take advantage of arena allocation, you need to use the arena
    APIs when creating messages. A quick example of using the arena API:

      {
        google::protobuf::Arena arena;
        // Allocate a protobuf message in the arena.
        MyMessage* message = Arena::CreateMessage<MyMessage>(&arena);
        // All submessages will be allocated in the same arena.
        if (!message->ParseFromString(data)) {
          // Deal with malformed input data.
        }
        // Must not delete the message here. It will be deleted automatically
        // when the arena is destroyed.
      }

    Currently arena does not work with map fields. Enabling arena in a .proto
    file containing map fields will result in compile errors in the generated
    code. This will be addressed in a future release.

2014-10-20 version 2.6.1:

  C++
  * Added atomicops support for Solaris.
  * Released memory allocated by InitializeDefaultRepeatedFields() and
    GetEmptyString(). Some memory sanitizers reported them as memory leaks.

  Java
  * Updated DynamicMessage.setField() to handle repeated enum values
    correctly.
  * Fixed a bug that caused NullPointerException to be thrown when
    converting manually constructed FileDescriptorProto to
    FileDescriptor.

  Python
  * Fixed WhichOneof() to work with de-serialized protobuf messages.
  * Fixed a missing file problem of Python C++ implementation.

2014-08-15 version 2.6.0:

  General
  * Added oneofs(unions) feature. Fields in the same oneof will share
    memory and at most one field can be set at the same time. Use the
    oneof keyword to define a oneof like:
      message SampleMessage {
        oneof test_oneof {
          string name = 4;
          YourMessage sub_message = 9;
        }
      }
  * Files, services, enums, messages, methods and enum values can be marked
    as deprecated now.
  * Added Support for list values, including lists of mesaages, when
    parsing text-formatted protos in C++ and Java.
      For example:  foo: [1, 2, 3]

  C++
  * Enhanced customization on TestFormat printing.
  * Added SwapFields() in reflection API to swap a subset of fields.
    Added SetAllocatedMessage() in reflection API.
  * Repeated primitive extensions are now packable. The
    [packed=true] option only affects serializers. Therefore, it is
    possible to switch a repeated extension field to packed format
    without breaking backwards-compatibility.
  * Various speed optimizations.

  Java
  * writeTo() method in ByteString can now write a substring to an
    output stream. Added endWith() method for ByteString.
  * ByteString and ByteBuffer are now supported in CodedInputStream
    and CodedOutputStream.
  * java_generate_equals_and_hash can now be used with the LITE_RUNTIME.

  Python
  * A new C++-backed extension module (aka "cpp api v2") that replaces the
    old ("cpp api v1") one.  Much faster than the pure Python code.  This one
    resolves many bugs and is recommended for general use over the
    pure Python when possible.
  * Descriptors now have enum_types_by_name and extension_types_by_name dict
    attributes.
  * Support for Python 3.

2013-02-27 version 2.5.0:

  General
  * New notion "import public" that allows a proto file to forward the content
    it imports to its importers. For example,
      // foo.proto
      import public "bar.proto";
      import "baz.proto";

      // qux.proto
      import "foo.proto";
      // Stuff defined in bar.proto may be used in this file, but stuff from
      // baz.proto may NOT be used without importing it explicitly.
    This is useful for moving proto files. To move a proto file, just leave
    a single "import public" in the old proto file.
  * New enum option "allow_alias" that specifies whether different symbols can
    be assigned the same numeric value. Default value is "true". Setting it to
    false causes the compiler to reject enum definitions where multiple symbols
    have the same numeric value.
    Note: We plan to flip the default value to "false" in a future release.
    Projects using enum aliases should set the option to "true" in their .proto
    files.

  C++
  * New generated method set_allocated_foo(Type* foo) for message and string
    fields. This method allows you to set the field to a pre-allocated object
    and the containing message takes the ownership of that object.
  * Added SetAllocatedExtension() and ReleaseExtension() to extensions API.
  * Custom options are now formatted correctly when descriptors are printed in
    text format.
  * Various speed optimizations.

  Java
  * Comments in proto files are now collected and put into generated code as
    comments for corresponding classes and data members.
  * Added Parser to parse directly into messages without a Builder. For
    example,
      Foo foo = Foo.PARSER.ParseFrom(input);
    Using Parser is ~25% faster than using Builder to parse messages.
  * Added getters/setters to access the underlying ByteString of a string field
    directly.
  * ByteString now supports more operations: substring(), prepend(), and
    append(). The implementation of ByteString uses a binary tree structure
    to support these operations efficiently.
  * New method findInitializationErrors() that lists all missing required
    fields.
  * Various code size and speed optimizations.

  Python
  * Added support for dynamic message creation. DescriptorDatabase,
    DescriptorPool, and MessageFactory work like their C++ couterparts to
    simplify Descriptor construction from *DescriptorProtos, and MessageFactory
    provides a message instance from a Descriptor.
  * Added pickle support for protobuf messages.
  * Unknown fields are now preserved after parsing.
  * Fixed bug where custom options were not correctly populated. Custom
    options can be accessed now.
  * Added EnumTypeWrapper that provides better accessibility to enum types.
  * Added ParseMessage(descriptor, bytes) to generate a new Message instance
    from a descriptor and a byte string.

2011-05-01 version 2.4.1:

  C++
  * Fixed the frendship problem for old compilers to make the library now gcc 3
    compatible again.
  * Fixed vcprojects/extract_includes.bat to extract compiler/plugin.h.

  Java
  * Removed usages of JDK 1.6 only features to make the library now JDK 1.5
    compatible again.
  * Fixed a bug about negative enum values.
  * serialVersionUID is now defined in generated messages for java serializing.
  * Fixed protoc to use java.lang.Object, which makes "Object" now a valid
    message name again.

  Python
  * Experimental C++ implementation now requires C++ protobuf library installed.
    See the README.txt in the python directory for details.

2011-02-02 version 2.4.0:

  General
  * The RPC (cc|java|py)_generic_services default value is now false instead of
    true.
  * Custom options can have aggregate types. For example,
      message MyOption {
        optional string comment = 1;
        optional string author = 2;
      }
      extend google.protobuf.FieldOptions {
        optional MyOption myoption = 12345;
      }
    This option can now be set as follows:
      message SomeType {
        optional int32 field = 1 [(myoption) = { comment:'x' author:'y' }];
      }

  C++
  * Various speed and code size optimizations.
  * Added a release_foo() method on string and message fields.
  * Fixed gzip_output_stream sub-stream handling.

  Java
  * Builders now maintain sub-builders for sub-messages. Use getFooBuilder() to
    get the builder for the sub-message "foo". This allows you to repeatedly
    modify deeply-nested sub-messages without rebuilding them.
  * Builder.build() no longer invalidates the Builder for generated messages
    (You may continue to modify it and then build another message).
  * Code generator will generate efficient equals() and hashCode()
    implementations if new option java_generate_equals_and_hash is enabled.
    (Otherwise, reflection-based implementations are used.)
  * Generated messages now implement Serializable.
  * Fields with [deprecated=true] will be marked with @Deprecated in Java.
  * Added lazy conversion of UTF-8 encoded strings to String objects to improve
    performance.
  * Various optimizations.
  * Enum value can be accessed directly, instead of calling getNumber() on the
    enum member.
  * For each enum value, an integer constant is also generated with the suffix
    _VALUE.

  Python
  * Added an experimental  C++ implementation for Python messages via a Python
    extension. Implementation type is controlled by an environment variable
    PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION (valid values: "cpp" and "python")
    The default value is currently "python" but will be changed to "cpp" in
    future release.
  * Improved performance on message instantiation significantly.
    Most of the work on message instantiation is done just once per message
    class, instead of once per message instance.
  * Improved performance on text message parsing.
  * Allow add() to forward keyword arguments to the concrete class.
      E.g. instead of
        item = repeated_field.add()
        item.foo = bar
        item.baz = quux
      You can do:
        repeated_field.add(foo=bar, baz=quux)
  * Added a sort() interface to the BaseContainer.
  * Added an extend() method to repeated composite fields.
  * Added UTF8 debug string support.

2010-01-08 version 2.3.0:

  General
  * Parsers for repeated numeric fields now always accept both packed and
    unpacked input.  The [packed=true] option only affects serializers.
    Therefore, it is possible to switch a field to packed format without
    breaking backwards-compatibility -- as long as all parties are using
    protobuf 2.3.0 or above, at least.
  * The generic RPC service code generated by the C++, Java, and Python
    generators can be disabled via file options:
      option cc_generic_services = false;
      option java_generic_services = false;
      option py_generic_services = false;
    This allows plugins to generate alternative code, possibly specific to some
    particular RPC implementation.

  protoc
  * Now supports a plugin system for code generators.  Plugins can generate
    code for new languages or inject additional code into the output of other
    code generators.  Plugins are just binaries which accept a protocol buffer
    on stdin and write a protocol buffer to stdout, so they may be written in
    any language.  See src/google/protobuf/compiler/plugin.proto.
    **WARNING**:  Plugins are experimental.  The interface may change in a
    future version.
  * If the output location ends in .zip or .jar, protoc will write its output
    to a zip/jar archive instead of a directory.  For example:
      protoc --java_out=myproto_srcs.jar --python_out=myproto.zip myproto.proto
    Currently the archive contents are not compressed, though this could change
    in the future.
  * inf, -inf, and nan can now be used as default values for float and double
    fields.

  C++
  * Various speed and code size optimizations.
  * DynamicMessageFactory is now fully thread-safe.
  * Message::Utf8DebugString() method is like DebugString() but avoids escaping
    UTF-8 bytes.
  * Compiled-in message types can now contain dynamic extensions, through use
    of CodedInputStream::SetExtensionRegistry().
  * Now compiles shared libraries (DLLs) by default on Cygwin and MinGW, to
    match other platforms.  Use --disable-shared to avoid this.

  Java
  * parseDelimitedFrom() and mergeDelimitedFrom() now detect EOF and return
    false/null instead of throwing an exception.
  * Fixed some initialization ordering bugs.
  * Fixes for OpenJDK 7.

  Python
  * 10-25 times faster than 2.2.0, still pure-Python.
  * Calling a mutating method on a sub-message always instantiates the message
    in its parent even if the mutating method doesn't actually mutate anything
    (e.g. parsing from an empty string).
  * Expanded descriptors a bit.

2009-08-11 version 2.2.0:

  C++
  * Lite mode:  The "optimize_for = LITE_RUNTIME" option causes the compiler
    to generate code which only depends libprotobuf-lite, which is much smaller
    than libprotobuf but lacks descriptors, reflection, and some other features.
  * Fixed bug where Message.Swap(Message) was only implemented for
    optimize_for_speed.  Swap now properly implemented in both modes
    (Issue 91).
  * Added RemoveLast and SwapElements(index1, index2) to Reflection
    interface for repeated elements.
  * Added Swap(Message) to Reflection interface.
  * Floating-point literals in generated code that are intended to be
    single-precision now explicitly have 'f' suffix to avoid pedantic warnings
    produced by some compilers.
  * The [deprecated=true] option now causes the C++ code generator to generate
    a GCC-style deprecation annotation (no-op on other compilers).
  * google::protobuf::GetEnumDescriptor<SomeGeneratedEnumType>() returns the
    EnumDescriptor for that type -- useful for templates which cannot call
    SomeGeneratedEnumType_descriptor().
  * Various optimizations and obscure bug fixes.

  Java
  * Lite mode:  The "optimize_for = LITE_RUNTIME" option causes the compiler
    to generate code which only depends libprotobuf-lite, which is much smaller
    than libprotobuf but lacks descriptors, reflection, and some other features.
  * Lots of style cleanups.

  Python
  * Fixed endianness bug with floats and doubles.
  * Text format parsing support.
  * Fix bug with parsing packed repeated fields in embedded messages.
  * Ability to initialize fields by passing keyword args to constructor.
  * Support iterators in extend and __setslice__ for containers.

2009-05-13 version 2.1.0:

  General
  * Repeated fields of primitive types (types other that string, group, and
    nested messages) may now use the option [packed = true] to get a more
    efficient encoding.  In the new encoding, the entire list is written
    as a single byte blob using the "length-delimited" wire type.  Within
    this blob, the individual values are encoded the same way they would
    be normally except without a tag before each value (thus, they are
    tightly "packed").
  * For each field, the generated code contains an integer constant assigned
    to the field number.  For example, the .proto file:
      message Foo { optional int bar_baz = 123; }
    would generate the following constants, all with the integer value 123:
      C++:     Foo::kBarBazFieldNumber
      Java:    Foo.BAR_BAZ_FIELD_NUMBER
      Python:  Foo.BAR_BAZ_FIELD_NUMBER
    Constants are also generated for extensions, with the same naming scheme.
    These constants may be used as switch cases.
  * Updated bundled Google Test to version 1.3.0.  Google Test is now bundled
    in its verbatim form as a nested autoconf package, so you can drop in any
    other version of Google Test if needed.
  * optimize_for = SPEED is now the default, by popular demand.  Use
    optimize_for = CODE_SIZE if code size is more important in your app.
  * It is now an error to define a default value for a repeated field.
    Previously, this was silently ignored (it had no effect on the generated
    code).
  * Fields can now be marked deprecated like:
      optional int32 foo = 1 [deprecated = true];
    Currently this does not have any actual effect, but in the future the code
    generators may generate deprecation annotations in each language.
  * Cross-compiling should now be possible using the --with-protoc option to
    configure.  See README.txt for more info.

  protoc
  * --error_format=msvs option causes errors to be printed in Visual Studio
    format, which should allow them to be clicked on in the build log to go
    directly to the error location.
  * The type name resolver will no longer resolve type names to fields.  For
    example, this now works:
      message Foo {}
      message Bar {
        optional int32 Foo = 1;
        optional Foo baz = 2;
      }
    Previously, the type of "baz" would resolve to "Bar.Foo", and you'd get
    an error because Bar.Foo is a field, not a type.  Now the type of "baz"
    resolves to the message type Foo.  This change is unlikely to make a
    difference to anyone who follows the Protocol Buffers style guide.

  C++
  * Several optimizations, including but not limited to:
    - Serialization, especially to flat arrays, is 10%-50% faster, possibly
      more for small objects.
    - Several descriptor operations which previously required locking no longer
      do.
    - Descriptors are now constructed lazily on first use, rather than at
      process startup time.  This should save memory in programs which do not
      use descriptors or reflection.
    - UnknownFieldSet completely redesigned to be more efficient (especially in
      terms of memory usage).
    - Various optimizations to reduce code size (though the serialization speed
      optimizations increased code size).
  * Message interface has method ParseFromBoundedZeroCopyStream() which parses
    a limited number of bytes from an input stream rather than parsing until
    EOF.
  * GzipInputStream and GzipOutputStream support reading/writing gzip- or
    zlib-compressed streams if zlib is available.
    (google/protobuf/io/gzip_stream.h)
  * DescriptorPool::FindAllExtensions() and corresponding
    DescriptorDatabase::FindAllExtensions() can be used to enumerate all
    extensions of a given type.
  * For each enum type Foo, protoc will generate functions:
      const string& Foo_Name(Foo value);
      bool Foo_Parse(const string& name, Foo* result);
    The former returns the name of the enum constant corresponding to the given
    value while the latter finds the value corresponding to a name.
  * RepeatedField and RepeatedPtrField now have back-insertion iterators.
  * String fields now have setters that take a char* and a size, in addition
    to the existing ones that took char* or const string&.
  * DescriptorPool::AllowUnknownDependencies() may be used to tell
    DescriptorPool to create placeholder descriptors for unknown entities
    referenced in a FileDescriptorProto.  This can allow you to parse a .proto
    file without having access to other .proto files that it imports, for
    example.
  * Updated gtest to latest version.  The gtest package is now included as a
    nested autoconf package, so it should be able to drop new versions into the
    "gtest" subdirectory without modification.

  Java
  * Fixed bug where Message.mergeFrom(Message) failed to merge extensions.
  * Message interface has new method toBuilder() which is equivalent to
    newBuilderForType().mergeFrom(this).
  * All enums now implement the ProtocolMessageEnum interface.
  * Setting a field to null now throws NullPointerException.
  * Fixed tendency for TextFormat's parsing to overflow the stack when
    parsing large string values.  The underlying problem is with Java's
    regex implementation (which unfortunately uses recursive backtracking
    rather than building an NFA).  Worked around by making use of possesive
    quantifiers.
  * Generated service classes now also generate pure interfaces.  For a service
    Foo, Foo.Interface is a pure interface containing all of the service's
    defined methods.  Foo.newReflectiveService() can be called to wrap an
    instance of this interface in a class that implements the generic
    RpcService interface, which provides reflection support that is usually
    needed by RPC server implementations.
  * RPC interfaces now support blocking operation in addition to non-blocking.
    The protocol compiler generates separate blocking and non-blocking stubs
    which operate against separate blocking and non-blocking RPC interfaces.
    RPC implementations will have to implement the new interfaces in order to
    support blocking mode.
  * New I/O methods parseDelimitedFrom(), mergeDelimitedFrom(), and
    writeDelimitedTo() read and write "delemited" messages from/to a stream,
    meaning that the message size precedes the data.  This way, you can write
    multiple messages to a stream without having to worry about delimiting
    them yourself.
  * Throw a more descriptive exception when build() is double-called.
  * Add a method to query whether CodedInputStream is at the end of the input
    stream.
  * Add a method to reset a CodedInputStream's size counter; useful when
    reading many messages with the same stream.
  * equals() and hashCode() now account for unknown fields.

  Python
  * Added slicing support for repeated scalar fields. Added slice retrieval and
    removal of repeated composite fields.
  * Updated RPC interfaces to allow for blocking operation.  A client may
    now pass None for a callback when making an RPC, in which case the
    call will block until the response is received, and the response
    object will be returned directly to the caller.  This interface change
    cannot be used in practice until RPC implementations are updated to
    implement it.
  * Changes to input_stream.py should make protobuf compatible with appengine.

2008-11-25 version 2.0.3:

  protoc
  * Enum values may now have custom options, using syntax similar to field
    options.
  * Fixed bug where .proto files which use custom options but don't actually
    define them (i.e. they import another .proto file defining the options)
    had to explicitly import descriptor.proto.
  * Adjacent string literals in .proto files will now be concatenated, like in
    C.
  * If an input file is a Windows absolute path (e.g. "C:\foo\bar.proto") and
    the import path only contains "." (or contains "." but does not contain
    the file), protoc incorrectly thought that the file was under ".", because
    it thought that the path was relative (since it didn't start with a slash).
    This has been fixed.

  C++
  * Generated message classes now have a Swap() method which efficiently swaps
    the contents of two objects.
  * All message classes now have a SpaceUsed() method which returns an estimate
    of the number of bytes of allocated memory currently owned by the object.
    This is particularly useful when you are reusing a single message object
    to improve performance but want to make sure it doesn't bloat up too large.
  * New method Message::SerializeAsString() returns a string containing the
    serialized data.  May be more convenient than calling
    SerializeToString(string*).
  * In debug mode, log error messages when string-type fields are found to
    contain bytes that are not valid UTF-8.
  * Fixed bug where a message with multiple extension ranges couldn't parse
    extensions.
  * Fixed bug where MergeFrom(const Message&) didn't do anything if invoked on
    a message that contained no fields (but possibly contained extensions).
  * Fixed ShortDebugString() to not be O(n^2).  Durr.
  * Fixed crash in TextFormat parsing if the first token in the input caused a
    tokenization error.
  * Fixed obscure bugs in zero_copy_stream_impl.cc.
  * Added support for HP C++ on Tru64.
  * Only build tests on "make check", not "make".
  * Fixed alignment issue that caused crashes when using DynamicMessage on
    64-bit Sparc machines.
  * Simplify template usage to work with MSVC 2003.
  * Work around GCC 4.3.x x86_64 compiler bug that caused crashes on startup.
    (This affected Fedora 9 in particular.)
  * Now works on "Solaris 10 using recent Sun Studio".

  Java
  * New overload of mergeFrom() which parses a slice of a byte array instead
    of the whole thing.
  * New method ByteString.asReadOnlyByteBuffer() does what it sounds like.
  * Improved performance of isInitialized() when optimizing for code size.

  Python
  * Corrected ListFields() signature in Message base class to match what
    subclasses actually implement.
  * Some minor refactoring.
  * Don't pass self as first argument to superclass constructor (no longer
    allowed in Python 2.6).

2008-09-29 version 2.0.2:

  General
  * License changed from Apache 2.0 to New BSD.
  * It is now possible to define custom "options", which are basically
    annotations which may be placed on definitions in a .proto file.
    For example, you might define a field option called "foo" like so:
      import "google/protobuf/descriptor.proto"
      extend google.protobuf.FieldOptions {
        optional string foo = 12345;
      }
    Then you annotate a field using the "foo" option:
      message MyMessage {
        optional int32 some_field = 1 [(foo) = "bar"]
      }
    The value of this option is then visible via the message's
    Descriptor:
      const FieldDescriptor* field =
        MyMessage::descriptor()->FindFieldByName("some_field");
      assert(field->options().GetExtension(foo) == "bar");
    This feature has been implemented and tested in C++ and Java.
    Other languages may or may not need to do extra work to support
    custom options, depending on how they construct descriptors.

  C++
  * Fixed some GCC warnings that only occur when using -pedantic.
  * Improved static initialization code, making ordering more
    predictable among other things.
  * TextFormat will no longer accept messages which contain multiple
    instances of a singular field.  Previously, the latter instance
    would overwrite the former.
  * Now works on systems that don't have hash_map.

  Java
  * Print @Override annotation in generated code where appropriate.

  Python
  * Strings now use the "unicode" type rather than the "str" type.
    String fields may still be assigned ASCII "str" values; they will
    automatically be converted.
  * Adding a property to an object representing a repeated field now
    raises an exception.  For example:
      # No longer works (and never should have).
      message.some_repeated_field.foo = 1

  Windows
  * We now build static libraries rather than DLLs by default on MSVC.
    See vsprojects/readme.txt for more information.

2008-08-15 version 2.0.1:

  protoc
  * New flags --encode and --decode can be used to convert between protobuf text
    format and binary format from the command-line.
  * New flag --descriptor_set_out can be used to write FileDescriptorProtos for
    all parsed files directly into a single output file.  This is particularly
    useful if you wish to parse .proto files from programs written in languages
    other than C++: just run protoc as a background process and have it output
    a FileDescriptorList, then parse that natively.
  * Improved error message when an enum value's name conflicts with another
    symbol defined in the enum type's scope, e.g. if two enum types declared
    in the same scope have values with the same name.  This is disallowed for
    compatibility with C++, but this wasn't clear from the error.
  * Fixed absolute output paths on Windows.
  * Allow trailing slashes in --proto_path mappings.

  C++
  * Reflection objects are now per-class rather than per-instance.  To make this
    possible, the Reflection interface had to be changed such that all methods
    take the Message instance as a parameter.  This change improves performance
    significantly in memory-bandwidth-limited use cases, since it makes the
    message objects smaller.  Note that source-incompatible interface changes
    like this will not be made again after the library leaves beta.
  * Heuristically detect sub-messages when printing unknown fields.
  * Fix static initialization ordering bug that caused crashes at startup when
    compiling on Mac with static linking.
  * Fixed TokenizerTest when compiling with -DNDEBUG on Linux.
  * Fixed incorrect definition of kint32min.
  * Fix bytes type setter to work with byte sequences with embedded NULLs.
  * Other irrelevant tweaks.

  Java
  * Fixed UnknownFieldSet's parsing of varints larger than 32 bits.
  * Fixed TextFormat's parsing of "inf" and "nan".
  * Fixed TextFormat's parsing of comments.
  * Added info to Java POM that will be required when we upload the
    package to a Maven repo.

  Python
  * MergeFrom(message) and CopyFrom(message) are now implemented.
  * SerializeToString() raises an exception if the message is missing required
    fields.
  * Code organization improvements.
  * Fixed doc comments for RpcController and RpcChannel, which had somehow been
    swapped.
  * Fixed text_format_test on Windows where floating-point exponents sometimes
    contain extra zeros.
  * Fix Python service CallMethod() implementation.

  Other
  * Improved readmes.
  * VIM syntax highlighting improvements.

2008-07-07 version 2.0.0:

  * First public release.
