You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by st...@apache.org on 2017/07/06 03:58:31 UTC

[33/51] [partial] hbase git commit: HBASE-17056 Remove checked in PB generated files Selective add of dependency on hbase-thirdparty jars. Update to READMEs on how protobuf is done (and update to refguide) Removed all checked in generated protobuf files.

http://git-wip-us.apache.org/repos/asf/hbase/blob/df93c13f/hbase-protocol-shaded/src/main/java/org/apache/hadoop/hbase/shaded/com/google/protobuf/Descriptors.java
----------------------------------------------------------------------
diff --git a/hbase-protocol-shaded/src/main/java/org/apache/hadoop/hbase/shaded/com/google/protobuf/Descriptors.java b/hbase-protocol-shaded/src/main/java/org/apache/hadoop/hbase/shaded/com/google/protobuf/Descriptors.java
deleted file mode 100644
index 62ccd19..0000000
--- a/hbase-protocol-shaded/src/main/java/org/apache/hadoop/hbase/shaded/com/google/protobuf/Descriptors.java
+++ /dev/null
@@ -1,2547 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package org.apache.hadoop.hbase.shaded.com.google.protobuf;
-
-import org.apache.hadoop.hbase.shaded.com.google.protobuf.DescriptorProtos.*;
-import org.apache.hadoop.hbase.shaded.com.google.protobuf.Descriptors.FileDescriptor.Syntax;
-
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.WeakHashMap;
-import java.util.logging.Logger;
-
-/**
- * Contains a collection of classes which describe protocol message types.
- *
- * Every message type has a {@link Descriptor}, which lists all
- * its fields and other information about a type.  You can get a message
- * type's descriptor by calling {@code MessageType.getDescriptor()}, or
- * (given a message object of the type) {@code message.getDescriptorForType()}.
- * Furthermore, each message is associated with a {@link FileDescriptor} for
- * a relevant {@code .proto} file. You can obtain it by calling
- * {@code Descriptor.getFile()}. A {@link FileDescriptor} contains descriptors
- * for all the messages defined in that file, and file descriptors for all the
- * imported {@code .proto} files.
- *
- * Descriptors are built from DescriptorProtos, as defined in
- * {@code google/protobuf/descriptor.proto}.
- *
- * @author kenton@google.com Kenton Varda
- */
-public final class Descriptors {
-  private static final Logger logger =
-      Logger.getLogger(Descriptors.class.getName());
-  /**
-   * Describes a {@code .proto} file, including everything defined within.
-   * That includes, in particular, descriptors for all the messages and
-   * file descriptors for all other imported {@code .proto} files
-   * (dependencies).
-   */
-  public static final class FileDescriptor extends GenericDescriptor {
-    /** Convert the descriptor to its protocol message representation. */
-    @Override
-    public FileDescriptorProto toProto() {
-      return proto;
-    }
-
-    /** Get the file name. */
-    @Override
-    public String getName() {
-      return proto.getName();
-    }
-
-    /** Returns this object. */
-    @Override
-    public FileDescriptor getFile() {
-      return this;
-    }
-
-    /** Returns the same as getName(). */
-    @Override
-    public String getFullName() {
-      return proto.getName();
-    }
-
-    /**
-     * Get the proto package name.  This is the package name given by the
-     * {@code package} statement in the {@code .proto} file, which differs
-     * from the Java package.
-     */
-    public String getPackage() { return proto.getPackage(); }
-
-    /** Get the {@code FileOptions}, defined in {@code descriptor.proto}. */
-    public FileOptions getOptions() { return proto.getOptions(); }
-
-    /** Get a list of top-level message types declared in this file. */
-    public List<Descriptor> getMessageTypes() {
-      return Collections.unmodifiableList(Arrays.asList(messageTypes));
-    }
-
-    /** Get a list of top-level enum types declared in this file. */
-    public List<EnumDescriptor> getEnumTypes() {
-      return Collections.unmodifiableList(Arrays.asList(enumTypes));
-    }
-
-    /** Get a list of top-level services declared in this file. */
-    public List<ServiceDescriptor> getServices() {
-      return Collections.unmodifiableList(Arrays.asList(services));
-    }
-
-    /** Get a list of top-level extensions declared in this file. */
-    public List<FieldDescriptor> getExtensions() {
-      return Collections.unmodifiableList(Arrays.asList(extensions));
-    }
-
-    /** Get a list of this file's dependencies (imports). */
-    public List<FileDescriptor> getDependencies() {
-      return Collections.unmodifiableList(Arrays.asList(dependencies));
-    }
-
-    /** Get a list of this file's public dependencies (public imports). */
-    public List<FileDescriptor> getPublicDependencies() {
-      return Collections.unmodifiableList(Arrays.asList(publicDependencies));
-    }
-
-    /** The syntax of the .proto file. */
-    public enum Syntax {
-      UNKNOWN("unknown"),
-      PROTO2("proto2"),
-      PROTO3("proto3");
-
-      Syntax(String name) {
-        this.name = name;
-      }
-      private final String name;
-    }
-
-    /** Get the syntax of the .proto file. */
-    public Syntax getSyntax() {
-      if (Syntax.PROTO3.name.equals(proto.getSyntax())) {
-        return Syntax.PROTO3;
-      }
-      return Syntax.PROTO2;
-    }
-
-    /**
-     * Find a message type in the file by name.  Does not find nested types.
-     *
-     * @param name The unqualified type name to look for.
-     * @return The message type's descriptor, or {@code null} if not found.
-     */
-    public Descriptor findMessageTypeByName(String name) {
-      // Don't allow looking up nested types.  This will make optimization
-      // easier later.
-      if (name.indexOf('.') != -1) {
-        return null;
-      }
-      if (getPackage().length() > 0) {
-        name = getPackage() + '.' + name;
-      }
-      final GenericDescriptor result = pool.findSymbol(name);
-      if (result != null && result instanceof Descriptor &&
-          result.getFile() == this) {
-        return (Descriptor)result;
-      } else {
-        return null;
-      }
-    }
-
-    /**
-     * Find an enum type in the file by name.  Does not find nested types.
-     *
-     * @param name The unqualified type name to look for.
-     * @return The enum type's descriptor, or {@code null} if not found.
-     */
-    public EnumDescriptor findEnumTypeByName(String name) {
-      // Don't allow looking up nested types.  This will make optimization
-      // easier later.
-      if (name.indexOf('.') != -1) {
-        return null;
-      }
-      if (getPackage().length() > 0) {
-        name = getPackage() + '.' + name;
-      }
-      final GenericDescriptor result = pool.findSymbol(name);
-      if (result != null && result instanceof EnumDescriptor &&
-          result.getFile() == this) {
-        return (EnumDescriptor)result;
-      } else {
-        return null;
-      }
-    }
-
-    /**
-     * Find a service type in the file by name.
-     *
-     * @param name The unqualified type name to look for.
-     * @return The service type's descriptor, or {@code null} if not found.
-     */
-    public ServiceDescriptor findServiceByName(String name) {
-      // Don't allow looking up nested types.  This will make optimization
-      // easier later.
-      if (name.indexOf('.') != -1) {
-        return null;
-      }
-      if (getPackage().length() > 0) {
-        name = getPackage() + '.' + name;
-      }
-      final GenericDescriptor result = pool.findSymbol(name);
-      if (result != null && result instanceof ServiceDescriptor &&
-          result.getFile() == this) {
-        return (ServiceDescriptor)result;
-      } else {
-        return null;
-      }
-    }
-
-    /**
-     * Find an extension in the file by name.  Does not find extensions nested
-     * inside message types.
-     *
-     * @param name The unqualified extension name to look for.
-     * @return The extension's descriptor, or {@code null} if not found.
-     */
-    public FieldDescriptor findExtensionByName(String name) {
-      if (name.indexOf('.') != -1) {
-        return null;
-      }
-      if (getPackage().length() > 0) {
-        name = getPackage() + '.' + name;
-      }
-      final GenericDescriptor result = pool.findSymbol(name);
-      if (result != null && result instanceof FieldDescriptor &&
-          result.getFile() == this) {
-        return (FieldDescriptor)result;
-      } else {
-        return null;
-      }
-    }
-
-    /**
-     * Construct a {@code FileDescriptor}.
-     *
-     * @param proto The protocol message form of the FileDescriptor.
-     * @param dependencies {@code FileDescriptor}s corresponding to all of
-     *                     the file's dependencies.
-     * @throws DescriptorValidationException {@code proto} is not a valid
-     *           descriptor.  This can occur for a number of reasons, e.g.
-     *           because a field has an undefined type or because two messages
-     *           were defined with the same name.
-     */
-    public static FileDescriptor buildFrom(final FileDescriptorProto proto,
-                                           final FileDescriptor[] dependencies)
-                                    throws DescriptorValidationException {
-      return buildFrom(proto, dependencies, false);
-    }
-
-
-    /**
-     * Construct a {@code FileDescriptor}.
-     *
-     * @param proto The protocol message form of the FileDescriptor.
-     * @param dependencies {@code FileDescriptor}s corresponding to all of
-     *                     the file's dependencies.
-     * @param allowUnknownDependencies If true, non-exist dependenncies will be
-     *           ignored and undefined message types will be replaced with a
-     *           placeholder type.
-     * @throws DescriptorValidationException {@code proto} is not a valid
-     *           descriptor.  This can occur for a number of reasons, e.g.
-     *           because a field has an undefined type or because two messages
-     *           were defined with the same name.
-     */
-    public static FileDescriptor buildFrom(
-        final FileDescriptorProto proto, final FileDescriptor[] dependencies,
-        final boolean allowUnknownDependencies)
-        throws DescriptorValidationException {
-      // Building descriptors involves two steps:  translating and linking.
-      // In the translation step (implemented by FileDescriptor's
-      // constructor), we build an object tree mirroring the
-      // FileDescriptorProto's tree and put all of the descriptors into the
-      // DescriptorPool's lookup tables.  In the linking step, we look up all
-      // type references in the DescriptorPool, so that, for example, a
-      // FieldDescriptor for an embedded message contains a pointer directly
-      // to the Descriptor for that message's type.  We also detect undefined
-      // types in the linking step.
-      final DescriptorPool pool = new DescriptorPool(
-          dependencies, allowUnknownDependencies);
-      final FileDescriptor result = new FileDescriptor(
-          proto, dependencies, pool, allowUnknownDependencies);
-      result.crossLink();
-      return result;
-    }
-
-    /**
-     * This method is to be called by generated code only.  It is equivalent
-     * to {@code buildFrom} except that the {@code FileDescriptorProto} is
-     * encoded in protocol buffer wire format.
-     */
-    public static void internalBuildGeneratedFileFrom(
-        final String[] descriptorDataParts,
-        final FileDescriptor[] dependencies,
-        final InternalDescriptorAssigner descriptorAssigner) {
-      // Hack:  We can't embed a raw byte array inside generated Java code
-      //   (at least, not efficiently), but we can embed Strings.  So, the
-      //   protocol compiler embeds the FileDescriptorProto as a giant
-      //   string literal which is passed to this function to construct the
-      //   file's FileDescriptor.  The string literal contains only 8-bit
-      //   characters, each one representing a byte of the FileDescriptorProto's
-      //   serialized form.  So, if we convert it to bytes in ISO-8859-1, we
-      //   should get the original bytes that we want.
-
-      // descriptorData may contain multiple strings in order to get around the
-      // Java 64k string literal limit.
-      StringBuilder descriptorData = new StringBuilder();
-      for (String part : descriptorDataParts) {
-        descriptorData.append(part);
-      }
-
-      final byte[] descriptorBytes;
-      descriptorBytes = descriptorData.toString().getBytes(Internal.ISO_8859_1);
-
-      FileDescriptorProto proto;
-      try {
-        proto = FileDescriptorProto.parseFrom(descriptorBytes);
-      } catch (InvalidProtocolBufferException e) {
-        throw new IllegalArgumentException(
-          "Failed to parse protocol buffer descriptor for generated code.", e);
-      }
-
-      final FileDescriptor result;
-      try {
-        // When building descriptors for generated code, we allow unknown
-        // dependencies by default.
-        result = buildFrom(proto, dependencies, true);
-      } catch (DescriptorValidationException e) {
-        throw new IllegalArgumentException(
-          "Invalid embedded descriptor for \"" + proto.getName() + "\".", e);
-      }
-
-      final ExtensionRegistry registry =
-          descriptorAssigner.assignDescriptors(result);
-
-      if (registry != null) {
-        // We must re-parse the proto using the registry.
-        try {
-          proto = FileDescriptorProto.parseFrom(descriptorBytes, registry);
-        } catch (InvalidProtocolBufferException e) {
-          throw new IllegalArgumentException(
-            "Failed to parse protocol buffer descriptor for generated code.",
-            e);
-        }
-
-        result.setProto(proto);
-      }
-    }
-
-    /**
-     * This method is to be called by generated code only.  It uses Java
-     * reflection to load the dependencies' descriptors.
-     */
-    public static void internalBuildGeneratedFileFrom(
-        final String[] descriptorDataParts,
-        final Class<?> descriptorOuterClass,
-        final String[] dependencies,
-        final String[] dependencyFileNames,
-        final InternalDescriptorAssigner descriptorAssigner) {
-      List<FileDescriptor> descriptors = new ArrayList<FileDescriptor>();
-      for (int i = 0; i < dependencies.length; i++) {
-        try {
-          Class<?> clazz =
-              descriptorOuterClass.getClassLoader().loadClass(dependencies[i]);
-          descriptors.add(
-              (FileDescriptor) clazz.getField("descriptor").get(null));
-        } catch (Exception e) {
-          // We allow unknown dependencies by default. If a dependency cannot
-          // be found we only generate a warning.
-          logger.warning("Descriptors for \"" + dependencyFileNames[i] +
-              "\" can not be found.");
-        }
-      }
-      FileDescriptor[] descriptorArray = new FileDescriptor[descriptors.size()];
-      descriptors.toArray(descriptorArray);
-      internalBuildGeneratedFileFrom(
-          descriptorDataParts, descriptorArray, descriptorAssigner);
-    }
-
-    /**
-     * This method is to be called by generated code only.  It is used to
-     * update the FileDescriptorProto associated with the descriptor by
-     * parsing it again with the given ExtensionRegistry. This is needed to
-     * recognize custom options.
-     */
-    public static void internalUpdateFileDescriptor(
-        final FileDescriptor descriptor,
-        final ExtensionRegistry registry) {
-      ByteString bytes = descriptor.proto.toByteString();
-      FileDescriptorProto proto;
-      try {
-        proto = FileDescriptorProto.parseFrom(bytes, registry);
-      } catch (InvalidProtocolBufferException e) {
-        throw new IllegalArgumentException(
-          "Failed to parse protocol buffer descriptor for generated code.", e);
-      }
-      descriptor.setProto(proto);
-    }
-
-    /**
-     * This class should be used by generated code only.  When calling
-     * {@link FileDescriptor#internalBuildGeneratedFileFrom}, the caller
-     * provides a callback implementing this interface.  The callback is called
-     * after the FileDescriptor has been constructed, in order to assign all
-     * the global variables defined in the generated code which point at parts
-     * of the FileDescriptor.  The callback returns an ExtensionRegistry which
-     * contains any extensions which might be used in the descriptor -- that
-     * is, extensions of the various "Options" messages defined in
-     * descriptor.proto.  The callback may also return null to indicate that
-     * no extensions are used in the descriptor.
-     */
-    public interface InternalDescriptorAssigner {
-      ExtensionRegistry assignDescriptors(FileDescriptor root);
-    }
-
-    private FileDescriptorProto proto;
-    private final Descriptor[] messageTypes;
-    private final EnumDescriptor[] enumTypes;
-    private final ServiceDescriptor[] services;
-    private final FieldDescriptor[] extensions;
-    private final FileDescriptor[] dependencies;
-    private final FileDescriptor[] publicDependencies;
-    private final DescriptorPool pool;
-
-    private FileDescriptor(final FileDescriptorProto proto,
-                           final FileDescriptor[] dependencies,
-                           final DescriptorPool pool,
-                           boolean allowUnknownDependencies)
-                    throws DescriptorValidationException {
-      this.pool = pool;
-      this.proto = proto;
-      this.dependencies = dependencies.clone();
-      HashMap<String, FileDescriptor> nameToFileMap =
-          new HashMap<String, FileDescriptor>();
-      for (FileDescriptor file : dependencies) {
-        nameToFileMap.put(file.getName(), file);
-      }
-      List<FileDescriptor> publicDependencies = new ArrayList<FileDescriptor>();
-      for (int i = 0; i < proto.getPublicDependencyCount(); i++) {
-        int index = proto.getPublicDependency(i);
-        if (index < 0 || index >= proto.getDependencyCount()) {
-          throw new DescriptorValidationException(this,
-              "Invalid public dependency index.");
-        }
-        String name = proto.getDependency(index);
-        FileDescriptor file = nameToFileMap.get(name);
-        if (file == null) {
-          if (!allowUnknownDependencies) {
-            throw new DescriptorValidationException(this,
-                "Invalid public dependency: " + name);
-          }
-          // Ignore unknown dependencies.
-        } else {
-          publicDependencies.add(file);
-        }
-      }
-      this.publicDependencies = new FileDescriptor[publicDependencies.size()];
-      publicDependencies.toArray(this.publicDependencies);
-
-      pool.addPackage(getPackage(), this);
-
-      messageTypes = new Descriptor[proto.getMessageTypeCount()];
-      for (int i = 0; i < proto.getMessageTypeCount(); i++) {
-        messageTypes[i] =
-          new Descriptor(proto.getMessageType(i), this, null, i);
-      }
-
-      enumTypes = new EnumDescriptor[proto.getEnumTypeCount()];
-      for (int i = 0; i < proto.getEnumTypeCount(); i++) {
-        enumTypes[i] = new EnumDescriptor(proto.getEnumType(i), this, null, i);
-      }
-
-      services = new ServiceDescriptor[proto.getServiceCount()];
-      for (int i = 0; i < proto.getServiceCount(); i++) {
-        services[i] = new ServiceDescriptor(proto.getService(i), this, i);
-      }
-
-      extensions = new FieldDescriptor[proto.getExtensionCount()];
-      for (int i = 0; i < proto.getExtensionCount(); i++) {
-        extensions[i] = new FieldDescriptor(
-          proto.getExtension(i), this, null, i, true);
-      }
-    }
-
-    /**
-     * Create a placeholder FileDescriptor for a message Descriptor.
-     */
-    FileDescriptor(String packageName, Descriptor message)
-        throws DescriptorValidationException {
-      this.pool = new DescriptorPool(new FileDescriptor[0], true);
-      this.proto = FileDescriptorProto.newBuilder()
-          .setName(message.getFullName() + ".placeholder.proto")
-          .setPackage(packageName).addMessageType(message.toProto()).build();
-      this.dependencies = new FileDescriptor[0];
-      this.publicDependencies = new FileDescriptor[0];
-
-      messageTypes = new Descriptor[] {message};
-      enumTypes = new EnumDescriptor[0];
-      services = new ServiceDescriptor[0];
-      extensions = new FieldDescriptor[0];
-
-      pool.addPackage(packageName, this);
-      pool.addSymbol(message);
-    }
-
-    /** Look up and cross-link all field types, etc. */
-    private void crossLink() throws DescriptorValidationException {
-      for (final Descriptor messageType : messageTypes) {
-        messageType.crossLink();
-      }
-
-      for (final ServiceDescriptor service : services) {
-        service.crossLink();
-      }
-
-      for (final FieldDescriptor extension : extensions) {
-        extension.crossLink();
-      }
-    }
-
-    /**
-     * Replace our {@link FileDescriptorProto} with the given one, which is
-     * identical except that it might contain extensions that weren't present
-     * in the original.  This method is needed for bootstrapping when a file
-     * defines custom options.  The options may be defined in the file itself,
-     * so we can't actually parse them until we've constructed the descriptors,
-     * but to construct the descriptors we have to have parsed the descriptor
-     * protos.  So, we have to parse the descriptor protos a second time after
-     * constructing the descriptors.
-     */
-    private void setProto(final FileDescriptorProto proto) {
-      this.proto = proto;
-
-      for (int i = 0; i < messageTypes.length; i++) {
-        messageTypes[i].setProto(proto.getMessageType(i));
-      }
-
-      for (int i = 0; i < enumTypes.length; i++) {
-        enumTypes[i].setProto(proto.getEnumType(i));
-      }
-
-      for (int i = 0; i < services.length; i++) {
-        services[i].setProto(proto.getService(i));
-      }
-
-      for (int i = 0; i < extensions.length; i++) {
-        extensions[i].setProto(proto.getExtension(i));
-      }
-    }
-
-    boolean supportsUnknownEnumValue() {
-      return getSyntax() == Syntax.PROTO3;
-    }
-  }
-
-  // =================================================================
-
-  /** Describes a message type. */
-  public static final class Descriptor extends GenericDescriptor {
-    /**
-     * Get the index of this descriptor within its parent.  In other words,
-     * given a {@link FileDescriptor} {@code file}, the following is true:
-     * <pre>
-     *   for all i in [0, file.getMessageTypeCount()):
-     *     file.getMessageType(i).getIndex() == i
-     * </pre>
-     * Similarly, for a {@link Descriptor} {@code messageType}:
-     * <pre>
-     *   for all i in [0, messageType.getNestedTypeCount()):
-     *     messageType.getNestedType(i).getIndex() == i
-     * </pre>
-     */
-    public int getIndex() { return index; }
-
-    /** Convert the descriptor to its protocol message representation. */
-    @Override
-    public DescriptorProto toProto() {
-      return proto;
-    }
-
-    /** Get the type's unqualified name. */
-    @Override
-    public String getName() {
-      return proto.getName();
-    }
-
-    /**
-     * Get the type's fully-qualified name, within the proto language's
-     * namespace.  This differs from the Java name.  For example, given this
-     * {@code .proto}:
-     * <pre>
-     *   package foo.bar;
-     *   option java_package = "com.example.protos"
-     *   message Baz {}
-     * </pre>
-     * {@code Baz}'s full name is "foo.bar.Baz".
-     */
-    @Override
-    public String getFullName() {
-      return fullName;
-    }
-
-    /** Get the {@link FileDescriptor} containing this descriptor. */
-    @Override
-    public FileDescriptor getFile() {
-      return file;
-    }
-
-    /** If this is a nested type, get the outer descriptor, otherwise null. */
-    public Descriptor getContainingType() { return containingType; }
-
-    /** Get the {@code MessageOptions}, defined in {@code descriptor.proto}. */
-    public MessageOptions getOptions() { return proto.getOptions(); }
-
-    /** Get a list of this message type's fields. */
-    public List<FieldDescriptor> getFields() {
-      return Collections.unmodifiableList(Arrays.asList(fields));
-    }
-
-    /** Get a list of this message type's oneofs. */
-    public List<OneofDescriptor> getOneofs() {
-      return Collections.unmodifiableList(Arrays.asList(oneofs));
-    }
-
-    /** Get a list of this message type's extensions. */
-    public List<FieldDescriptor> getExtensions() {
-      return Collections.unmodifiableList(Arrays.asList(extensions));
-    }
-
-    /** Get a list of message types nested within this one. */
-    public List<Descriptor> getNestedTypes() {
-      return Collections.unmodifiableList(Arrays.asList(nestedTypes));
-    }
-
-    /** Get a list of enum types nested within this one. */
-    public List<EnumDescriptor> getEnumTypes() {
-      return Collections.unmodifiableList(Arrays.asList(enumTypes));
-    }
-
-    /** Determines if the given field number is an extension. */
-    public boolean isExtensionNumber(final int number) {
-      for (final DescriptorProto.ExtensionRange range :
-          proto.getExtensionRangeList()) {
-        if (range.getStart() <= number && number < range.getEnd()) {
-          return true;
-        }
-      }
-      return false;
-    }
-
-    /** Determines if the given field number is reserved. */
-    public boolean isReservedNumber(final int number) {
-      for (final DescriptorProto.ReservedRange range :
-          proto.getReservedRangeList()) {
-        if (range.getStart() <= number && number < range.getEnd()) {
-          return true;
-        }
-      }
-      return false;
-    }
-
-    /** Determines if the given field name is reserved. */
-    public boolean isReservedName(final String name) {
-      if (name == null) {
-        throw new NullPointerException();
-      }
-      for (final String reservedName : proto.getReservedNameList()) {
-        if (reservedName.equals(name)) {
-          return true;
-        }
-      }
-      return false;
-    }
-
-    /**
-     * Indicates whether the message can be extended.  That is, whether it has
-     * any "extensions x to y" ranges declared on it.
-     */
-    public boolean isExtendable() {
-      return proto.getExtensionRangeList().size() != 0;
-    }
-
-    /**
-     * Finds a field by name.
-     * @param name The unqualified name of the field (e.g. "foo").
-     * @return The field's descriptor, or {@code null} if not found.
-     */
-    public FieldDescriptor findFieldByName(final String name) {
-      final GenericDescriptor result =
-          file.pool.findSymbol(fullName + '.' + name);
-      if (result != null && result instanceof FieldDescriptor) {
-        return (FieldDescriptor)result;
-      } else {
-        return null;
-      }
-    }
-
-    /**
-     * Finds a field by field number.
-     * @param number The field number within this message type.
-     * @return The field's descriptor, or {@code null} if not found.
-     */
-    public FieldDescriptor findFieldByNumber(final int number) {
-      return file.pool.fieldsByNumber.get(
-        new DescriptorPool.DescriptorIntPair(this, number));
-    }
-
-    /**
-     * Finds a nested message type by name.
-     * @param name The unqualified name of the nested type (e.g. "Foo").
-     * @return The types's descriptor, or {@code null} if not found.
-     */
-    public Descriptor findNestedTypeByName(final String name) {
-      final GenericDescriptor result =
-          file.pool.findSymbol(fullName + '.' + name);
-      if (result != null && result instanceof Descriptor) {
-        return (Descriptor)result;
-      } else {
-        return null;
-      }
-    }
-
-    /**
-     * Finds a nested enum type by name.
-     * @param name The unqualified name of the nested type (e.g. "Foo").
-     * @return The types's descriptor, or {@code null} if not found.
-     */
-    public EnumDescriptor findEnumTypeByName(final String name) {
-      final GenericDescriptor result =
-          file.pool.findSymbol(fullName + '.' + name);
-      if (result != null && result instanceof EnumDescriptor) {
-        return (EnumDescriptor)result;
-      } else {
-        return null;
-      }
-    }
-
-    private final int index;
-    private DescriptorProto proto;
-    private final String fullName;
-    private final FileDescriptor file;
-    private final Descriptor containingType;
-    private final Descriptor[] nestedTypes;
-    private final EnumDescriptor[] enumTypes;
-    private final FieldDescriptor[] fields;
-    private final FieldDescriptor[] extensions;
-    private final OneofDescriptor[] oneofs;
-
-    // Used to create a placeholder when the type cannot be found.
-    Descriptor(final String fullname) throws DescriptorValidationException {
-      String name = fullname;
-      String packageName = "";
-      int pos = fullname.lastIndexOf('.');
-      if (pos != -1) {
-        name = fullname.substring(pos + 1);
-        packageName = fullname.substring(0, pos);
-      }
-      this.index = 0;
-      this.proto = DescriptorProto.newBuilder().setName(name).addExtensionRange(
-          DescriptorProto.ExtensionRange.newBuilder().setStart(1)
-          .setEnd(536870912).build()).build();
-      this.fullName = fullname;
-      this.containingType = null;
-
-      this.nestedTypes = new Descriptor[0];
-      this.enumTypes = new EnumDescriptor[0];
-      this.fields = new FieldDescriptor[0];
-      this.extensions = new FieldDescriptor[0];
-      this.oneofs = new OneofDescriptor[0];
-
-      // Create a placeholder FileDescriptor to hold this message.
-      this.file = new FileDescriptor(packageName, this);
-    }
-
-    private Descriptor(final DescriptorProto proto,
-                       final FileDescriptor file,
-                       final Descriptor parent,
-                       final int index)
-                throws DescriptorValidationException {
-      this.index = index;
-      this.proto = proto;
-      fullName = computeFullName(file, parent, proto.getName());
-      this.file = file;
-      containingType = parent;
-
-      oneofs = new OneofDescriptor[proto.getOneofDeclCount()];
-      for (int i = 0; i < proto.getOneofDeclCount(); i++) {
-        oneofs[i] = new OneofDescriptor(
-          proto.getOneofDecl(i), file, this, i);
-      }
-
-      nestedTypes = new Descriptor[proto.getNestedTypeCount()];
-      for (int i = 0; i < proto.getNestedTypeCount(); i++) {
-        nestedTypes[i] = new Descriptor(
-          proto.getNestedType(i), file, this, i);
-      }
-
-      enumTypes = new EnumDescriptor[proto.getEnumTypeCount()];
-      for (int i = 0; i < proto.getEnumTypeCount(); i++) {
-        enumTypes[i] = new EnumDescriptor(
-          proto.getEnumType(i), file, this, i);
-      }
-
-      fields = new FieldDescriptor[proto.getFieldCount()];
-      for (int i = 0; i < proto.getFieldCount(); i++) {
-        fields[i] = new FieldDescriptor(
-          proto.getField(i), file, this, i, false);
-      }
-
-      extensions = new FieldDescriptor[proto.getExtensionCount()];
-      for (int i = 0; i < proto.getExtensionCount(); i++) {
-        extensions[i] = new FieldDescriptor(
-          proto.getExtension(i), file, this, i, true);
-      }
-
-      for (int i = 0; i < proto.getOneofDeclCount(); i++) {
-        oneofs[i].fields = new FieldDescriptor[oneofs[i].getFieldCount()];
-        oneofs[i].fieldCount = 0;
-      }
-      for (int i = 0; i < proto.getFieldCount(); i++) {
-        OneofDescriptor oneofDescriptor = fields[i].getContainingOneof();
-        if (oneofDescriptor != null) {
-          oneofDescriptor.fields[oneofDescriptor.fieldCount++] = fields[i];
-        }
-      }
-
-      file.pool.addSymbol(this);
-    }
-
-    /** Look up and cross-link all field types, etc. */
-    private void crossLink() throws DescriptorValidationException {
-      for (final Descriptor nestedType : nestedTypes) {
-        nestedType.crossLink();
-      }
-
-      for (final FieldDescriptor field : fields) {
-        field.crossLink();
-      }
-
-      for (final FieldDescriptor extension : extensions) {
-        extension.crossLink();
-      }
-    }
-
-    /** See {@link FileDescriptor#setProto}. */
-    private void setProto(final DescriptorProto proto) {
-      this.proto = proto;
-
-      for (int i = 0; i < nestedTypes.length; i++) {
-        nestedTypes[i].setProto(proto.getNestedType(i));
-      }
-
-      for (int i = 0; i < oneofs.length; i++) {
-        oneofs[i].setProto(proto.getOneofDecl(i));
-      }
-
-      for (int i = 0; i < enumTypes.length; i++) {
-        enumTypes[i].setProto(proto.getEnumType(i));
-      }
-
-      for (int i = 0; i < fields.length; i++) {
-        fields[i].setProto(proto.getField(i));
-      }
-
-      for (int i = 0; i < extensions.length; i++) {
-        extensions[i].setProto(proto.getExtension(i));
-      }
-    }
-  }
-
-  // =================================================================
-
-  /** Describes a field of a message type. */
-  public static final class FieldDescriptor
-        extends GenericDescriptor
-        implements Comparable<FieldDescriptor>,
-                 FieldSet.FieldDescriptorLite<FieldDescriptor> {
-    /**
-     * Get the index of this descriptor within its parent.
-     * @see Descriptors.Descriptor#getIndex()
-     */
-    public int getIndex() { return index; }
-
-    /** Convert the descriptor to its protocol message representation. */
-    @Override
-    public FieldDescriptorProto toProto() {
-      return proto;
-    }
-
-    /** Get the field's unqualified name. */
-    @Override
-    public String getName() {
-      return proto.getName();
-    }
-
-    /** Get the field's number. */
-    @Override
-    public int getNumber() {
-      return proto.getNumber();
-    }
-
-    /**
-     * Get the field's fully-qualified name.
-     * @see Descriptors.Descriptor#getFullName()
-     */
-    @Override
-    public String getFullName() {
-      return fullName;
-    }
-
-    /** Get the JSON name of this field. */
-    public String getJsonName() {
-      return jsonName;
-    }
-
-    /**
-     * Get the field's java type.  This is just for convenience.  Every
-     * {@code FieldDescriptorProto.Type} maps to exactly one Java type.
-     */
-    public JavaType getJavaType() { return type.getJavaType(); }
-
-    /** For internal use only. */
-    @Override
-    public WireFormat.JavaType getLiteJavaType() {
-      return getLiteType().getJavaType();
-    }
-
-    /** Get the {@code FileDescriptor} containing this descriptor. */
-    @Override
-    public FileDescriptor getFile() {
-      return file;
-    }
-
-    /** Get the field's declared type. */
-    public Type getType() { return type; }
-
-    /** For internal use only. */
-    @Override
-    public WireFormat.FieldType getLiteType() {
-      return table[type.ordinal()];
-    }
-
-    /** For internal use only. */
-    public boolean needsUtf8Check() {
-      if (type != Type.STRING) {
-        return false;
-      }
-      if (getContainingType().getOptions().getMapEntry()) {
-        // Always enforce strict UTF-8 checking for map fields.
-        return true;
-      }
-      if (getFile().getSyntax() == Syntax.PROTO3) {
-        return true;
-      }
-      return getFile().getOptions().getJavaStringCheckUtf8();
-    }
-
-    public boolean isMapField() {
-      return getType() == Type.MESSAGE && isRepeated()
-          && getMessageType().getOptions().getMapEntry();
-    }
-
-    // I'm pretty sure values() constructs a new array every time, since there
-    // is nothing stopping the caller from mutating the array.  Therefore we
-    // make a static copy here.
-    private static final WireFormat.FieldType[] table =
-        WireFormat.FieldType.values();
-
-    /** Is this field declared required? */
-    public boolean isRequired() {
-      return proto.getLabel() == FieldDescriptorProto.Label.LABEL_REQUIRED;
-    }
-
-    /** Is this field declared optional? */
-    public boolean isOptional() {
-      return proto.getLabel() == FieldDescriptorProto.Label.LABEL_OPTIONAL;
-    }
-
-    /** Is this field declared repeated? */
-    @Override
-    public boolean isRepeated() {
-      return proto.getLabel() == FieldDescriptorProto.Label.LABEL_REPEATED;
-    }
-
-    /** Does this field have the {@code [packed = true]} option or is this field
-     *  packable in proto3 and not explicitly setted to unpacked?
-     */
-    @Override
-    public boolean isPacked() {
-      if (!isPackable()) {
-        return false;
-      }
-      if (getFile().getSyntax() == FileDescriptor.Syntax.PROTO2) {
-        return getOptions().getPacked();
-      } else {
-        return !getOptions().hasPacked() || getOptions().getPacked();
-      }
-    }
-
-    /** Can this field be packed? i.e. is it a repeated primitive field? */
-    public boolean isPackable() {
-      return isRepeated() && getLiteType().isPackable();
-    }
-
-    /** Returns true if the field had an explicitly-defined default value. */
-    public boolean hasDefaultValue() { return proto.hasDefaultValue(); }
-
-    /**
-     * Returns the field's default value.  Valid for all types except for
-     * messages and groups.  For all other types, the object returned is of
-     * the same class that would returned by Message.getField(this).
-     */
-    public Object getDefaultValue() {
-      if (getJavaType() == JavaType.MESSAGE) {
-        throw new UnsupportedOperationException(
-          "FieldDescriptor.getDefaultValue() called on an embedded message " +
-          "field.");
-      }
-      return defaultValue;
-    }
-
-    /** Get the {@code FieldOptions}, defined in {@code descriptor.proto}. */
-    public FieldOptions getOptions() { return proto.getOptions(); }
-
-    /** Is this field an extension? */
-    public boolean isExtension() { return proto.hasExtendee(); }
-
-    /**
-     * Get the field's containing type. For extensions, this is the type being
-     * extended, not the location where the extension was defined.  See
-     * {@link #getExtensionScope()}.
-     */
-    public Descriptor getContainingType() { return containingType; }
-
-    /** Get the field's containing oneof. */
-    public OneofDescriptor getContainingOneof() { return containingOneof; }
-
-    /**
-     * For extensions defined nested within message types, gets the outer
-     * type.  Not valid for non-extension fields.  For example, consider
-     * this {@code .proto} file:
-     * <pre>
-     *   message Foo {
-     *     extensions 1000 to max;
-     *   }
-     *   extend Foo {
-     *     optional int32 baz = 1234;
-     *   }
-     *   message Bar {
-     *     extend Foo {
-     *       optional int32 qux = 4321;
-     *     }
-     *   }
-     * </pre>
-     * Both {@code baz}'s and {@code qux}'s containing type is {@code Foo}.
-     * However, {@code baz}'s extension scope is {@code null} while
-     * {@code qux}'s extension scope is {@code Bar}.
-     */
-    public Descriptor getExtensionScope() {
-      if (!isExtension()) {
-        throw new UnsupportedOperationException(
-          "This field is not an extension.");
-      }
-      return extensionScope;
-    }
-
-    /** For embedded message and group fields, gets the field's type. */
-    public Descriptor getMessageType() {
-      if (getJavaType() != JavaType.MESSAGE) {
-        throw new UnsupportedOperationException(
-          "This field is not of message type.");
-      }
-      return messageType;
-    }
-
-    /** For enum fields, gets the field's type. */
-    @Override
-    public EnumDescriptor getEnumType() {
-      if (getJavaType() != JavaType.ENUM) {
-        throw new UnsupportedOperationException(
-          "This field is not of enum type.");
-      }
-      return enumType;
-    }
-
-    /**
-     * Compare with another {@code FieldDescriptor}.  This orders fields in
-     * "canonical" order, which simply means ascending order by field number.
-     * {@code other} must be a field of the same type -- i.e.
-     * {@code getContainingType()} must return the same {@code Descriptor} for
-     * both fields.
-     *
-     * @return negative, zero, or positive if {@code this} is less than,
-     *         equal to, or greater than {@code other}, respectively.
-     */
-    @Override
-    public int compareTo(final FieldDescriptor other) {
-      if (other.containingType != containingType) {
-        throw new IllegalArgumentException(
-          "FieldDescriptors can only be compared to other FieldDescriptors " +
-          "for fields of the same message type.");
-      }
-      return getNumber() - other.getNumber();
-    }
-
-    @Override
-    public String toString() {
-      return getFullName();
-    }
-
-    private final int index;
-
-    private FieldDescriptorProto proto;
-    private final String fullName;
-    private final String jsonName;
-    private final FileDescriptor file;
-    private final Descriptor extensionScope;
-
-    // Possibly initialized during cross-linking.
-    private Type type;
-    private Descriptor containingType;
-    private Descriptor messageType;
-    private OneofDescriptor containingOneof;
-    private EnumDescriptor enumType;
-    private Object defaultValue;
-
-    public enum Type {
-      DOUBLE  (JavaType.DOUBLE     ),
-      FLOAT   (JavaType.FLOAT      ),
-      INT64   (JavaType.LONG       ),
-      UINT64  (JavaType.LONG       ),
-      INT32   (JavaType.INT        ),
-      FIXED64 (JavaType.LONG       ),
-      FIXED32 (JavaType.INT        ),
-      BOOL    (JavaType.BOOLEAN    ),
-      STRING  (JavaType.STRING     ),
-      GROUP   (JavaType.MESSAGE    ),
-      MESSAGE (JavaType.MESSAGE    ),
-      BYTES   (JavaType.BYTE_STRING),
-      UINT32  (JavaType.INT        ),
-      ENUM    (JavaType.ENUM       ),
-      SFIXED32(JavaType.INT        ),
-      SFIXED64(JavaType.LONG       ),
-      SINT32  (JavaType.INT        ),
-      SINT64  (JavaType.LONG       );
-
-      Type(final JavaType javaType) {
-        this.javaType = javaType;
-      }
-
-      private JavaType javaType;
-
-      public FieldDescriptorProto.Type toProto() {
-        return FieldDescriptorProto.Type.forNumber(ordinal() + 1);
-      }
-      public JavaType getJavaType() { return javaType; }
-
-      public static Type valueOf(final FieldDescriptorProto.Type type) {
-        return values()[type.getNumber() - 1];
-      }
-    }
-
-    static {
-      // Refuse to init if someone added a new declared type.
-      if (Type.values().length != FieldDescriptorProto.Type.values().length) {
-        throw new RuntimeException(""
-            + "descriptor.proto has a new declared type but Descriptors.java "
-            + "wasn't updated.");
-      }
-    }
-
-    public enum JavaType {
-      INT(0),
-      LONG(0L),
-      FLOAT(0F),
-      DOUBLE(0D),
-      BOOLEAN(false),
-      STRING(""),
-      BYTE_STRING(ByteString.EMPTY),
-      ENUM(null),
-      MESSAGE(null);
-
-      JavaType(final Object defaultDefault) {
-        this.defaultDefault = defaultDefault;
-      }
-
-      /**
-       * The default default value for fields of this type, if it's a primitive
-       * type.  This is meant for use inside this file only, hence is private.
-       */
-      private final Object defaultDefault;
-    }
-
-    // This method should match exactly with the ToJsonName() function in C++
-    // descriptor.cc.
-    private static String fieldNameToJsonName(String name) {
-      StringBuilder result = new StringBuilder(name.length());
-      boolean isNextUpperCase = false;
-      for (int i = 0; i < name.length(); i++) {
-        Character ch = name.charAt(i);
-        if (ch == '_') {
-          isNextUpperCase = true;
-        } else if (isNextUpperCase) {
-          result.append(Character.toUpperCase(ch));
-          isNextUpperCase = false;
-        } else {
-          result.append(ch);
-        }
-      }
-      return result.toString();
-    }
-
-    private FieldDescriptor(final FieldDescriptorProto proto,
-                            final FileDescriptor file,
-                            final Descriptor parent,
-                            final int index,
-                            final boolean isExtension)
-                     throws DescriptorValidationException {
-      this.index = index;
-      this.proto = proto;
-      fullName = computeFullName(file, parent, proto.getName());
-      this.file = file;
-      if (proto.hasJsonName()) {
-        jsonName = proto.getJsonName();
-      } else {
-        jsonName = fieldNameToJsonName(proto.getName());
-      }
-
-      if (proto.hasType()) {
-        type = Type.valueOf(proto.getType());
-      }
-
-      if (getNumber() <= 0) {
-        throw new DescriptorValidationException(this,
-          "Field numbers must be positive integers.");
-      }
-
-      if (isExtension) {
-        if (!proto.hasExtendee()) {
-          throw new DescriptorValidationException(this,
-            "FieldDescriptorProto.extendee not set for extension field.");
-        }
-        containingType = null;  // Will be filled in when cross-linking
-        if (parent != null) {
-          extensionScope = parent;
-        } else {
-          extensionScope = null;
-        }
-
-        if (proto.hasOneofIndex()) {
-          throw new DescriptorValidationException(this,
-            "FieldDescriptorProto.oneof_index set for extension field.");
-        }
-        containingOneof = null;
-      } else {
-        if (proto.hasExtendee()) {
-          throw new DescriptorValidationException(this,
-            "FieldDescriptorProto.extendee set for non-extension field.");
-        }
-        containingType = parent;
-
-        if (proto.hasOneofIndex()) {
-          if (proto.getOneofIndex() < 0 ||
-              proto.getOneofIndex() >= parent.toProto().getOneofDeclCount()) {
-            throw new DescriptorValidationException(this,
-              "FieldDescriptorProto.oneof_index is out of range for type "
-              + parent.getName());
-          }
-          containingOneof = parent.getOneofs().get(proto.getOneofIndex());
-          containingOneof.fieldCount++;
-        } else {
-          containingOneof = null;
-        }
-        extensionScope = null;
-      }
-
-      file.pool.addSymbol(this);
-    }
-
-    /** Look up and cross-link all field types, etc. */
-    private void crossLink() throws DescriptorValidationException {
-      if (proto.hasExtendee()) {
-        final GenericDescriptor extendee =
-          file.pool.lookupSymbol(proto.getExtendee(), this,
-              DescriptorPool.SearchFilter.TYPES_ONLY);
-        if (!(extendee instanceof Descriptor)) {
-          throw new DescriptorValidationException(this,
-              '\"' + proto.getExtendee() + "\" is not a message type.");
-        }
-        containingType = (Descriptor)extendee;
-
-        if (!getContainingType().isExtensionNumber(getNumber())) {
-          throw new DescriptorValidationException(this,
-              '\"' + getContainingType().getFullName() +
-              "\" does not declare " + getNumber() +
-              " as an extension number.");
-        }
-      }
-
-      if (proto.hasTypeName()) {
-        final GenericDescriptor typeDescriptor =
-          file.pool.lookupSymbol(proto.getTypeName(), this,
-              DescriptorPool.SearchFilter.TYPES_ONLY);
-
-        if (!proto.hasType()) {
-          // Choose field type based on symbol.
-          if (typeDescriptor instanceof Descriptor) {
-            type = Type.MESSAGE;
-          } else if (typeDescriptor instanceof EnumDescriptor) {
-            type = Type.ENUM;
-          } else {
-            throw new DescriptorValidationException(this,
-                '\"' + proto.getTypeName() + "\" is not a type.");
-          }
-        }
-
-        if (getJavaType() == JavaType.MESSAGE) {
-          if (!(typeDescriptor instanceof Descriptor)) {
-            throw new DescriptorValidationException(this,
-                '\"' + proto.getTypeName() + "\" is not a message type.");
-          }
-          messageType = (Descriptor)typeDescriptor;
-
-          if (proto.hasDefaultValue()) {
-            throw new DescriptorValidationException(this,
-              "Messages can't have default values.");
-          }
-        } else if (getJavaType() == JavaType.ENUM) {
-          if (!(typeDescriptor instanceof EnumDescriptor)) {
-            throw new DescriptorValidationException(this,
-                '\"' + proto.getTypeName() + "\" is not an enum type.");
-          }
-          enumType = (EnumDescriptor)typeDescriptor;
-        } else {
-          throw new DescriptorValidationException(this,
-            "Field with primitive type has type_name.");
-        }
-      } else {
-        if (getJavaType() == JavaType.MESSAGE ||
-            getJavaType() == JavaType.ENUM) {
-          throw new DescriptorValidationException(this,
-            "Field with message or enum type missing type_name.");
-        }
-      }
-
-      // Only repeated primitive fields may be packed.
-      if (proto.getOptions().getPacked() && !isPackable()) {
-        throw new DescriptorValidationException(this,
-          "[packed = true] can only be specified for repeated primitive " +
-          "fields.");
-      }
-
-      // We don't attempt to parse the default value until here because for
-      // enums we need the enum type's descriptor.
-      if (proto.hasDefaultValue()) {
-        if (isRepeated()) {
-          throw new DescriptorValidationException(this,
-            "Repeated fields cannot have default values.");
-        }
-
-        try {
-          switch (getType()) {
-            case INT32:
-            case SINT32:
-            case SFIXED32:
-              defaultValue = TextFormat.parseInt32(proto.getDefaultValue());
-              break;
-            case UINT32:
-            case FIXED32:
-              defaultValue = TextFormat.parseUInt32(proto.getDefaultValue());
-              break;
-            case INT64:
-            case SINT64:
-            case SFIXED64:
-              defaultValue = TextFormat.parseInt64(proto.getDefaultValue());
-              break;
-            case UINT64:
-            case FIXED64:
-              defaultValue = TextFormat.parseUInt64(proto.getDefaultValue());
-              break;
-            case FLOAT:
-              if (proto.getDefaultValue().equals("inf")) {
-                defaultValue = Float.POSITIVE_INFINITY;
-              } else if (proto.getDefaultValue().equals("-inf")) {
-                defaultValue = Float.NEGATIVE_INFINITY;
-              } else if (proto.getDefaultValue().equals("nan")) {
-                defaultValue = Float.NaN;
-              } else {
-                defaultValue = Float.valueOf(proto.getDefaultValue());
-              }
-              break;
-            case DOUBLE:
-              if (proto.getDefaultValue().equals("inf")) {
-                defaultValue = Double.POSITIVE_INFINITY;
-              } else if (proto.getDefaultValue().equals("-inf")) {
-                defaultValue = Double.NEGATIVE_INFINITY;
-              } else if (proto.getDefaultValue().equals("nan")) {
-                defaultValue = Double.NaN;
-              } else {
-                defaultValue = Double.valueOf(proto.getDefaultValue());
-              }
-              break;
-            case BOOL:
-              defaultValue = Boolean.valueOf(proto.getDefaultValue());
-              break;
-            case STRING:
-              defaultValue = proto.getDefaultValue();
-              break;
-            case BYTES:
-              try {
-                defaultValue =
-                  TextFormat.unescapeBytes(proto.getDefaultValue());
-              } catch (TextFormat.InvalidEscapeSequenceException e) {
-                throw new DescriptorValidationException(this,
-                  "Couldn't parse default value: " + e.getMessage(), e);
-              }
-              break;
-            case ENUM:
-              defaultValue = enumType.findValueByName(proto.getDefaultValue());
-              if (defaultValue == null) {
-                throw new DescriptorValidationException(this,
-                  "Unknown enum default value: \"" +
-                  proto.getDefaultValue() + '\"');
-              }
-              break;
-            case MESSAGE:
-            case GROUP:
-              throw new DescriptorValidationException(this,
-                "Message type had default value.");
-          }
-        } catch (NumberFormatException e) {
-          throw new DescriptorValidationException(this,
-              "Could not parse default value: \"" +
-              proto.getDefaultValue() + '\"', e);
-        }
-      } else {
-        // Determine the default default for this field.
-        if (isRepeated()) {
-          defaultValue = Collections.emptyList();
-        } else {
-          switch (getJavaType()) {
-            case ENUM:
-              // We guarantee elsewhere that an enum type always has at least
-              // one possible value.
-              defaultValue = enumType.getValues().get(0);
-              break;
-            case MESSAGE:
-              defaultValue = null;
-              break;
-            default:
-              defaultValue = getJavaType().defaultDefault;
-              break;
-          }
-        }
-      }
-
-      if (!isExtension()) {
-        file.pool.addFieldByNumber(this);
-      }
-
-      if (containingType != null &&
-          containingType.getOptions().getMessageSetWireFormat()) {
-        if (isExtension()) {
-          if (!isOptional() || getType() != Type.MESSAGE) {
-            throw new DescriptorValidationException(this,
-              "Extensions of MessageSets must be optional messages.");
-          }
-        } else {
-          throw new DescriptorValidationException(this,
-            "MessageSets cannot have fields, only extensions.");
-        }
-      }
-    }
-
-    /** See {@link FileDescriptor#setProto}. */
-    private void setProto(final FieldDescriptorProto proto) {
-      this.proto = proto;
-    }
-
-    /**
-     * For internal use only.  This is to satisfy the FieldDescriptorLite
-     * interface.
-     */
-    @Override
-    public MessageLite.Builder internalMergeFrom(MessageLite.Builder to, MessageLite from) {
-      // FieldDescriptors are only used with non-lite messages so we can just
-      // down-cast and call mergeFrom directly.
-      return ((Message.Builder) to).mergeFrom((Message) from);
-    }
-
-  }
-
-  // =================================================================
-
-  /** Describes an enum type. */
-  public static final class EnumDescriptor extends GenericDescriptor
-      implements Internal.EnumLiteMap<EnumValueDescriptor> {
-    /**
-     * Get the index of this descriptor within its parent.
-     * @see Descriptors.Descriptor#getIndex()
-     */
-    public int getIndex() { return index; }
-
-    /** Convert the descriptor to its protocol message representation. */
-    @Override
-    public EnumDescriptorProto toProto() {
-      return proto;
-    }
-
-    /** Get the type's unqualified name. */
-    @Override
-    public String getName() {
-      return proto.getName();
-    }
-
-    /**
-     * Get the type's fully-qualified name.
-     * @see Descriptors.Descriptor#getFullName()
-     */
-    @Override
-    public String getFullName() {
-      return fullName;
-    }
-
-    /** Get the {@link FileDescriptor} containing this descriptor. */
-    @Override
-    public FileDescriptor getFile() {
-      return file;
-    }
-
-    /** If this is a nested type, get the outer descriptor, otherwise null. */
-    public Descriptor getContainingType() { return containingType; }
-
-    /** Get the {@code EnumOptions}, defined in {@code descriptor.proto}. */
-    public EnumOptions getOptions() { return proto.getOptions(); }
-
-    /** Get a list of defined values for this enum. */
-    public List<EnumValueDescriptor> getValues() {
-      return Collections.unmodifiableList(Arrays.asList(values));
-    }
-
-    /**
-     * Find an enum value by name.
-     * @param name The unqualified name of the value (e.g. "FOO").
-     * @return the value's descriptor, or {@code null} if not found.
-     */
-    public EnumValueDescriptor findValueByName(final String name) {
-      final GenericDescriptor result =
-          file.pool.findSymbol(fullName + '.' + name);
-      if (result != null && result instanceof EnumValueDescriptor) {
-        return (EnumValueDescriptor)result;
-      } else {
-        return null;
-      }
-    }
-
-    /**
-     * Find an enum value by number.  If multiple enum values have the same
-     * number, this returns the first defined value with that number.
-     * @param number The value's number.
-     * @return the value's descriptor, or {@code null} if not found.
-     */
-    @Override
-    public EnumValueDescriptor findValueByNumber(final int number) {
-      return file.pool.enumValuesByNumber.get(
-        new DescriptorPool.DescriptorIntPair(this, number));
-    }
-
-    /**
-     * Get the enum value for a number. If no enum value has this number,
-     * construct an EnumValueDescriptor for it.
-     */
-    public EnumValueDescriptor findValueByNumberCreatingIfUnknown(final int number) {
-      EnumValueDescriptor result = findValueByNumber(number);
-      if (result != null) {
-        return result;
-      }
-      // The number represents an unknown enum value.
-      synchronized (this) {
-        // Descriptors are compared by object identity so for the same number
-        // we need to return the same EnumValueDescriptor object. This means
-        // we have to store created EnumValueDescriptors. However, as there
-        // are potentially 2G unknown enum values, storing all of these
-        // objects persistently will consume lots of memory for long-running
-        // services and it's also unnecessary as not many EnumValueDescriptors
-        // will be used at the same time.
-        //
-        // To solve the problem we take advantage of Java's weak references and
-        // rely on gc to release unused descriptors.
-        //
-        // Here is how it works:
-        //   * We store unknown EnumValueDescriptors in a WeakHashMap with the
-        //     value being a weak reference to the descriptor.
-        //   * The descriptor holds a strong reference to the key so as long
-        //     as the EnumValueDescriptor is in use, the key will be there
-        //     and the corresponding map entry will be there. Following-up
-        //     queries with the same number will return the same descriptor.
-        //   * If the user no longer uses an unknown EnumValueDescriptor,
-        //     it will be gc-ed since we only hold a weak reference to it in
-        //     the map. The key in the corresponding map entry will also be
-        //     gc-ed as the only strong reference to it is in the descriptor
-        //     which is just gc-ed. With the key being gone WeakHashMap will
-        //     then remove the whole entry. This way unknown descriptors will
-        //     be freed automatically and we don't need to do anything to
-        //     clean-up unused map entries.
-
-        // Note: We must use "new Integer(number)" here because we don't want
-        // these Integer objects to be cached.
-        Integer key = new Integer(number);
-        WeakReference<EnumValueDescriptor> reference = unknownValues.get(key);
-        if (reference != null) {
-          result = reference.get();
-        }
-        if (result == null) {
-          result = new EnumValueDescriptor(file, this, key);
-          unknownValues.put(key, new WeakReference<EnumValueDescriptor>(result));
-        }
-      }
-      return result;
-    }
-
-    // Used in tests only.
-    int getUnknownEnumValueDescriptorCount() {
-      return unknownValues.size();
-    }
-
-    private final int index;
-    private EnumDescriptorProto proto;
-    private final String fullName;
-    private final FileDescriptor file;
-    private final Descriptor containingType;
-    private EnumValueDescriptor[] values;
-    private final WeakHashMap<Integer, WeakReference<EnumValueDescriptor>> unknownValues =
-        new WeakHashMap<Integer, WeakReference<EnumValueDescriptor>>();
-
-    private EnumDescriptor(final EnumDescriptorProto proto,
-                           final FileDescriptor file,
-                           final Descriptor parent,
-                           final int index)
-                    throws DescriptorValidationException {
-      this.index = index;
-      this.proto = proto;
-      fullName = computeFullName(file, parent, proto.getName());
-      this.file = file;
-      containingType = parent;
-
-      if (proto.getValueCount() == 0) {
-        // We cannot allow enums with no values because this would mean there
-        // would be no valid default value for fields of this type.
-        throw new DescriptorValidationException(this,
-          "Enums must contain at least one value.");
-      }
-
-      values = new EnumValueDescriptor[proto.getValueCount()];
-      for (int i = 0; i < proto.getValueCount(); i++) {
-        values[i] = new EnumValueDescriptor(
-          proto.getValue(i), file, this, i);
-      }
-
-      file.pool.addSymbol(this);
-    }
-
-    /** See {@link FileDescriptor#setProto}. */
-    private void setProto(final EnumDescriptorProto proto) {
-      this.proto = proto;
-
-      for (int i = 0; i < values.length; i++) {
-        values[i].setProto(proto.getValue(i));
-      }
-    }
-  }
-
-  // =================================================================
-
-  /**
-   * Describes one value within an enum type.  Note that multiple defined
-   * values may have the same number.  In generated Java code, all values
-   * with the same number after the first become aliases of the first.
-   * However, they still have independent EnumValueDescriptors.
-   */
-  public static final class EnumValueDescriptor extends GenericDescriptor
-      implements Internal.EnumLite {
-    /**
-     * Get the index of this descriptor within its parent.
-     * @see Descriptors.Descriptor#getIndex()
-     */
-    public int getIndex() { return index; }
-
-    /** Convert the descriptor to its protocol message representation. */
-    @Override
-    public EnumValueDescriptorProto toProto() {
-      return proto;
-    }
-
-    /** Get the value's unqualified name. */
-    @Override
-    public String getName() {
-      return proto.getName();
-    }
-
-    /** Get the value's number. */
-    @Override
-    public int getNumber() {
-      return proto.getNumber();
-    }
-
-    @Override
-    public String toString() { return proto.getName(); }
-
-    /**
-     * Get the value's fully-qualified name.
-     * @see Descriptors.Descriptor#getFullName()
-     */
-    @Override
-    public String getFullName() {
-      return fullName;
-    }
-
-    /** Get the {@link FileDescriptor} containing this descriptor. */
-    @Override
-    public FileDescriptor getFile() {
-      return file;
-    }
-
-    /** Get the value's enum type. */
-    public EnumDescriptor getType() { return type; }
-
-    /**
-     * Get the {@code EnumValueOptions}, defined in {@code descriptor.proto}.
-     */
-    public EnumValueOptions getOptions() { return proto.getOptions(); }
-
-    private final int index;
-    private EnumValueDescriptorProto proto;
-    private final String fullName;
-    private final FileDescriptor file;
-    private final EnumDescriptor type;
-
-    private EnumValueDescriptor(final EnumValueDescriptorProto proto,
-                                final FileDescriptor file,
-                                final EnumDescriptor parent,
-                                final int index)
-                         throws DescriptorValidationException {
-      this.index = index;
-      this.proto = proto;
-      this.file = file;
-      type = parent;
-
-      fullName = parent.getFullName() + '.' + proto.getName();
-
-      file.pool.addSymbol(this);
-      file.pool.addEnumValueByNumber(this);
-    }
-
-    private Integer number;
-    // Create an unknown enum value.
-    private EnumValueDescriptor(
-        final FileDescriptor file,
-        final EnumDescriptor parent,
-        final Integer number) {
-      String name = "UNKNOWN_ENUM_VALUE_" + parent.getName() + "_" + number;
-      EnumValueDescriptorProto proto = EnumValueDescriptorProto
-          .newBuilder().setName(name).setNumber(number).build();
-      this.index = -1;
-      this.proto = proto;
-      this.file = file;
-      this.type = parent;
-      this.fullName = parent.getFullName() + '.' + proto.getName();
-      this.number = number;
-
-      // Don't add this descriptor into pool.
-    }
-
-    /** See {@link FileDescriptor#setProto}. */
-    private void setProto(final EnumValueDescriptorProto proto) {
-      this.proto = proto;
-    }
-  }
-
-  // =================================================================
-
-  /** Describes a service type. */
-  public static final class ServiceDescriptor extends GenericDescriptor {
-    /**
-     * Get the index of this descriptor within its parent.
-     * * @see Descriptors.Descriptor#getIndex()
-     */
-    public int getIndex() { return index; }
-
-    /** Convert the descriptor to its protocol message representation. */
-    @Override
-    public ServiceDescriptorProto toProto() {
-      return proto;
-    }
-
-    /** Get the type's unqualified name. */
-    @Override
-    public String getName() {
-      return proto.getName();
-    }
-
-    /**
-     * Get the type's fully-qualified name.
-     * @see Descriptors.Descriptor#getFullName()
-     */
-    @Override
-    public String getFullName() {
-      return fullName;
-    }
-
-    /** Get the {@link FileDescriptor} containing this descriptor. */
-    @Override
-    public FileDescriptor getFile() {
-      return file;
-    }
-
-    /** Get the {@code ServiceOptions}, defined in {@code descriptor.proto}. */
-    public ServiceOptions getOptions() { return proto.getOptions(); }
-
-    /** Get a list of methods for this service. */
-    public List<MethodDescriptor> getMethods() {
-      return Collections.unmodifiableList(Arrays.asList(methods));
-    }
-
-    /**
-     * Find a method by name.
-     * @param name The unqualified name of the method (e.g. "Foo").
-     * @return the method's descriptor, or {@code null} if not found.
-     */
-    public MethodDescriptor findMethodByName(final String name) {
-      final GenericDescriptor result =
-          file.pool.findSymbol(fullName + '.' + name);
-      if (result != null && result instanceof MethodDescriptor) {
-        return (MethodDescriptor)result;
-      } else {
-        return null;
-      }
-    }
-
-    private final int index;
-    private ServiceDescriptorProto proto;
-    private final String fullName;
-    private final FileDescriptor file;
-    private MethodDescriptor[] methods;
-
-    private ServiceDescriptor(final ServiceDescriptorProto proto,
-                              final FileDescriptor file,
-                              final int index)
-                       throws DescriptorValidationException {
-      this.index = index;
-      this.proto = proto;
-      fullName = computeFullName(file, null, proto.getName());
-      this.file = file;
-
-      methods = new MethodDescriptor[proto.getMethodCount()];
-      for (int i = 0; i < proto.getMethodCount(); i++) {
-        methods[i] = new MethodDescriptor(
-          proto.getMethod(i), file, this, i);
-      }
-
-      file.pool.addSymbol(this);
-    }
-
-    private void crossLink() throws DescriptorValidationException {
-      for (final MethodDescriptor method : methods) {
-        method.crossLink();
-      }
-    }
-
-    /** See {@link FileDescriptor#setProto}. */
-    private void setProto(final ServiceDescriptorProto proto) {
-      this.proto = proto;
-
-      for (int i = 0; i < methods.length; i++) {
-        methods[i].setProto(proto.getMethod(i));
-      }
-    }
-  }
-
-  // =================================================================
-
-  /**
-   * Describes one method within a service type.
-   */
-  public static final class MethodDescriptor extends GenericDescriptor {
-    /**
-     * Get the index of this descriptor within its parent.
-     * * @see Descriptors.Descriptor#getIndex()
-     */
-    public int getIndex() { return index; }
-
-    /** Convert the descriptor to its protocol message representation. */
-    @Override
-    public MethodDescriptorProto toProto() {
-      return proto;
-    }
-
-    /** Get the method's unqualified name. */
-    @Override
-    public String getName() {
-      return proto.getName();
-    }
-
-    /**
-     * Get the method's fully-qualified name.
-     * @see Descriptors.Descriptor#getFullName()
-     */
-    @Override
-    public String getFullName() {
-      return fullName;
-    }
-
-    /** Get the {@link FileDescriptor} containing this descriptor. */
-    @Override
-    public FileDescriptor getFile() {
-      return file;
-    }
-
-    /** Get the method's service type. */
-    public ServiceDescriptor getService() { return service; }
-
-    /** Get the method's input type. */
-    public Descriptor getInputType() { return inputType; }
-
-    /** Get the method's output type. */
-    public Descriptor getOutputType() { return outputType; }
-
-    /**
-     * Get the {@code MethodOptions}, defined in {@code descriptor.proto}.
-     */
-    public MethodOptions getOptions() { return proto.getOptions(); }
-
-    private final int index;
-    private MethodDescriptorProto proto;
-    private final String fullName;
-    private final FileDescriptor file;
-    private final ServiceDescriptor service;
-
-    // Initialized during cross-linking.
-    private Descriptor inputType;
-    private Descriptor outputType;
-
-    private MethodDescriptor(final MethodDescriptorProto proto,
-                             final FileDescriptor file,
-                             final ServiceDescriptor parent,
-                             final int index)
-                      throws DescriptorValidationException {
-      this.index = index;
-      this.proto = proto;
-      this.file = file;
-      service = parent;
-
-      fullName = parent.getFullName() + '.' + proto.getName();
-
-      file.pool.addSymbol(this);
-    }
-
-    private void crossLink() throws DescriptorValidationException {
-      final GenericDescriptor input =
-        file.pool.lookupSymbol(proto.getInputType(), this,
-            DescriptorPool.SearchFilter.TYPES_ONLY);
-      if (!(input instanceof Descriptor)) {
-        throw new DescriptorValidationException(this,
-            '\"' + proto.getInputType() + "\" is not a message type.");
-      }
-      inputType = (Descriptor)input;
-
-      final GenericDescriptor output =
-        file.pool.lookupSymbol(proto.getOutputType(), this,
-            DescriptorPool.SearchFilter.TYPES_ONLY);
-      if (!(output instanceof Descriptor)) {
-        throw new DescriptorValidationException(this,
-            '\"' + proto.getOutputType() + "\" is not a message type.");
-      }
-      outputType = (Descriptor)output;
-    }
-
-    /** See {@link FileDescriptor#setProto}. */
-    private void setProto(final MethodDescriptorProto proto) {
-      this.proto = proto;
-    }
-  }
-
-  // =================================================================
-
-  private static String computeFullName(final FileDescriptor file,
-                                        final Descriptor parent,
-                                        final String name) {
-    if (parent != null) {
-      return parent.getFullName() + '.' + name;
-    } else if (file.getPackage().length() > 0) {
-      return file.getPackage() + '.' + name;
-    } else {
-      return name;
-    }
-  }
-
-  // =================================================================
-
-  /**
-   * All descriptors implement this to make it easier to implement tools like
-   * {@code DescriptorPool}.<p>
-   *
-   * This class is public so that the methods it exposes can be called from
-   * outside of this package. However, it should only be subclassed from
-   * nested classes of Descriptors.
-   */
-  public abstract static class GenericDescriptor {
-    public abstract Message toProto();
-    public abstract String getName();
-    public abstract String getFullName();
-    public abstract FileDescriptor getFile();
-  }
-
-  /**
-   * Thrown when building descriptors fails because the source DescriptorProtos
-   * are not valid.
-   */
-  public static class DescriptorValidationException extends Exception {
-    private static final long serialVersionUID = 5750205775490483148L;
-
-    /** Gets the full name of the descriptor where the error occurred. */
-    public String getProblemSymbolName() { return name; }
-
-    /**
-     * Gets the protocol message representation of the invalid descriptor.
-     */
-    public Message getProblemProto() { return proto; }
-
-    /**
-     * Gets a human-readable description of the error.
-     */
-    public String getDescription() { return description; }
-
-    private final String name;
-    private final Message proto;
-    private final String description;
-
-    private DescriptorValidationException(
-        final GenericDescriptor problemDescriptor,
-        final String description) {
-      super(problemDescriptor.getFullName() + ": " + description);
-
-      // Note that problemDescriptor may be partially uninitialized, so we
-      // don't want to expose it directly to the user.  So, we only provide
-      // the name and the original proto.
-      name = problemDescriptor.getFullName();
-      proto = problemDescriptor.toProto();
-      this.description = description;
-    }
-
-    private DescriptorValidationException(
-        final GenericDescriptor problemDescriptor,
-        final String description,
-        final Throwable cause) {
-      this(problemDescriptor, description);
-      initCause(cause);
-    }
-
-    private DescriptorValidationException(
-        final FileDescriptor problemDescriptor,
-        final String description) {
-      super(problemDescriptor.getName() + ": " + description);
-
-      // Note that problemDescriptor may be partially uninitialized, so we
-      // don't want to expose it directly to the user.  So, we only provide
-      // the name and the original proto.
-      name = problemDescriptor.getName();
-      proto = problemDescriptor.toProto();
-      this.description = description;
-    }
-  }
-
-  // =================================================================
-
-  /**
-   * A private helper class which contains lookup tables containing all the
-   * descriptors defined in a particular file.
-   */
-  private static final class DescriptorPool {
-
-    /** Defines what subclass of descriptors to search in the descriptor pool.
-     */
-    enum SearchFilter {
-      TYPES_ONLY, AGGREGATES_ONLY, ALL_SYMBOLS
-    }
-
-    DescriptorPool(final FileDescriptor[] dependencies,
-        boolean allowUnknownDependencies) {
-      this.dependencies = new HashSet<FileDescriptor>();
-      this.allowUnknownDependencies = allowUnknownDependencies;
-
-      for (int i = 0; i < dependencies.length; i++) {
-        this.dependencies.add(dependencies[i]);
-        importPublicDependencies(dependencies[i]);
-      }
-
-      for (final FileDescriptor dependency : this.dependencies) {
-        try {
-          addPackage(dependency.getPackage(), dependency);
-        } catch (DescriptorValidationException e) {
-          // Can't happen, because addPackage() only fails when the name
-          // conflicts with a non-package, but we have not yet added any
-          // non-packages at this point.
-          throw new AssertionError(e);
-        }
-      }
-    }
-
-    /** Find and put public dependencies of the file into dependencies set.*/
-    private void importPublicDependencies(final FileDescriptor file) {
-      for (FileDescriptor dependency : file.getPublicDependencies()) {
-        if (dependencies.add(dependency)) {
-          importPublicDependencies(dependency);
-        }
-      }
-    }
-
-    private final Set<FileDescriptor> dependencies;
-    private boolean allowUnknownDependencies;
-
-    private final Map<String, GenericDescriptor> descriptorsByName =
-      new HashMap<String, GenericDescriptor>();
-    private final Map<DescriptorIntPair, FieldDescriptor> fieldsByNumber =
-      new HashMap<DescriptorIntPair, FieldDescriptor>();
-    private final Map<DescriptorIntPair, EnumValueDescriptor> enumValuesByNumber
-        = new HashMap<DescriptorIntPair, EnumValueDescriptor>();
-
-    /** Find a generic descriptor by fully-qualified name. */
-    GenericDescriptor findSymbol(final String fullName) {
-      return findSymbol(fullName, SearchFilter.ALL_SYMBOLS);
-    }
-
-    /** Find a descriptor by fully-qualified name and given option to only
-     * search valid field type descriptors.
-     */
-    GenericDescriptor findSymbol(final String fullName,
-                                 final SearchFilter filter) {
-      GenericDescriptor result = descriptorsByName.get(fullName);
-      if (result != null) {
-        if ((filter==SearchFilter.ALL_SYMBOLS) ||
-            ((filter==SearchFilter.TYPES_ONLY) && isType(result)) ||
-            ((filter==SearchFilter.AGGREGATES_ONLY) && isAggregate(result))) {
-          return result;
-        }
-      }
-
-      for (final FileDescriptor dependency : dependencies) {
-        result = dependency.pool.descriptorsByName.get(fullName);
-        if (result != null) {
-          if ((filter==SearchFilter.ALL_SYMBOLS) ||
-              ((filter==SearchFilter.TYPES_ONLY) && isType(result)) ||
-              ((filter==SearchFilter.AGGREGATES_ONLY) && isAggregate(result))) {
-            return result;
-          }
-        }
-      }
-
-      return null;
-    }
-
-    /** Checks if the descriptor is a valid type for a message field. */
-    boolean isType(GenericDescriptor descriptor) {
-      return (descriptor instanceof Descriptor) ||
-        (descriptor instanceof EnumDescriptor);
-    }
-
-    /** Checks if the descriptor is a valid namespace type. */
-    boolean isAggregate(GenericDescriptor descriptor) {
-      return (descriptor instanceof Descriptor) ||
-        (descriptor instanceof EnumDescriptor) ||
-        (descriptor instanceof PackageDescriptor) ||
-        (descriptor instanceof ServiceDescriptor);
-    }
-
-    /**
-     * Look up a type descriptor by name, relative to some other descriptor.
-     * The name may be fully-qualified (with a leading '.'),
-     * partially-qualified, or unqualified.  C++-like name lookup semantics
-     * are used to search for the matching descriptor.
-     */
-    GenericDescriptor lookupSymbol(final String name,
-                                   final GenericDescriptor relativeTo,
-                                   final DescriptorPool.SearchFilter filter)
-                            throws DescriptorValidationException {
-      // TODO(kenton):  This could be optimized in a number of ways.
-
-      GenericDescriptor result;
-      String fullname;
-      if (name.startsWith(".")) {
-        // Fully-qualified name.
-        fullname = name.substring(1);
-        result = findSymbol(fullname, filter);
-      } else {
-        // If "name" is a compound identifier, we want to search for the
-        // first component of it, then search within it for the rest.
-        // If name is something like "Foo.Bar.baz", and symbols named "Foo" are
-        // defined in multiple parent scopes, we only want to find "Bar.baz" in
-        // the innermost one.  E.g., the following should produce an error:
-        //   message Bar { message Baz {} }
-        //   message Foo {
-        //     message Bar {
-        //     }
-        //     optional Bar.Baz baz = 1;
-        //   }
-        // So, we look for just "Foo" first, then look for "Bar.baz" within it
-        // if found.
-        final int firstPartLength = name.indexOf('.');
-        final String firstPart;
-        if (firstPartLength == -1) {
-          firstPart = name;
-        } else {
-          firstPart = name.substring(0, firstPartLength);
-        }
-
-        // We will search each parent scope of "relativeTo" looking for the
-        // symbol.
-        final StringBuilder scopeToTry =
-            new StringBuilder(relativeTo.getFullName());
-
-        while (true) {
-          // Chop off the last component of the scope.
-          final int dotpos = scopeToTry.lastIndexOf(".");
-          if (dotpos == -1) {
-            fullname = name;
-            result = findSymbol(name, filter);
-            break;
-          } else {
-            scopeToTry.setLength(dotpos + 1);
-
-            // Append firstPart and try to find
-            scopeToTry.append(firstPart);
-            result = findSymbol(scopeToTry.toString(),
-                DescriptorPool.SearchFilter.AGGREGATES_ONLY);
-
-            if (result != null) {
-              if (firstPartLength != -1) {
-                // We only found the first part of the symbol.  Now look for
-                // the whole thing.  If this fails, we *don't* want to keep
-                // searching parent scopes.
-                scopeToTry.setLength(dotpos + 1);
-                scopeToTry.append(name);
-                result = findSymbol(scopeToTry.toString(), filter);
-              }
-              fullname = scopeToTry.toString();
-              break;
-            }
-
-            // Not found.  Remove the name so we can try again.
-            scopeToTry.setLength(dotpos);
-          }
-        }
-      }
-
-      if (result == null) {
-        if (allowUnknownDependencies && filter == SearchFilter.TYPES_ONLY) {
-          logger.warning("The descriptor for message type \"" + name +
-              "\" can not be found and a placeholder is created for it");
-          // We create a dummy message descriptor here regardless of the
-          // expected type. If the type should be message, this dummy
-          // descriptor will work well and if the type should be enum, a
-          // DescriptorValidationException will be thrown latter. In either
-          // case, the code works as expected: we allow unknown message types
-          // but not unknwon enum types.
-          result = new Descriptor(fullname);
-          // Add the placeholder file as a dependency so we can find the
-          // placeholder symbol when resolving other references.
-          this.dependencies.add(result.getFile());
-          return result;
-        } else {
-          throw new DescriptorValidationException(relativeTo,
-              '\"' + name + "\" is not defined.");
-        }
-      } else {
-        return result;
-      }
-    }
-
-    /**
-     * Adds a symbol to the symbol table.  If a symbol with the same name
-     * already exists, throws an error.
-     */
-    void addSymbol(final GenericDescriptor descriptor)
-            throws DescriptorValidationException {
-      validateSymbolName(descriptor);
-
-      final String fullName = descriptor.getFullName();
-      final int dotpos = fullName.lastIndexOf('.');
-
-      final GenericDescriptor old = descriptorsByName.put(fullName, descriptor);
-      if (old != null) {
-        descriptorsByName.put(fullName, old);
-
-        if (descriptor.getFile() == old.getFile()) {
-          if (dotpos == -1) {
-            throw new DescriptorValidationException(descriptor,
-                '\"' + fullName + "\" is already defined.");
-          } else {
-            throw new DescriptorValidationException(descriptor,
-                '\"' + fullName.substring(dotpos + 1) +
-              "\" is already defined in \"" +
-              fullName.substring(0, dotpos) + "\".");
-          }
-        } else {
-          throw new DescriptorValidationException(descriptor,
-              '\"' + fullName + "\" is already defined in file \"" +
-            old.getFile().getName() + "\".");
-        }
-      }
-    }
-
-    /**
-     * Represents a package in the symbol table.  We use PackageDescriptors
-     * just as placeholders so that someone cannot define, say, a message type
-     * that has the same name as an existing package.
-     */
-    private static final class PackageDescriptor extends GenericDescriptor {
-      @Override
-      public Message toProto() {
-        return file.toProto();
-      }
-      @Override
-      public String getName() {
-        return name;
-      }
-      @Override
-      public String getFullName() {
-        return fullName;
-      }
-      @Override
-      public FileDescriptor getFile() {
-        return file;
-      }
-
-      PackageDescriptor(final String name, final String fullName,
-                        final FileDescriptor file) {
-        this.file = file;
-        this.fullName = fullName;
-        this.name = name;
-      }
-
-      private final String name;
-      private final String fullName;
-      private final FileDescriptor file;
-    }
-
-    /**
-     * Adds a package to the symbol tables.  If a package by the same name
-     * already exists, that is fine, but if some other kind of symbol exists
-     * under the same name, an exception is thrown.  If the package has
-     * multiple components, this also adds the parent package(s).
-     */
-    void addPackage(final String fullName, final FileDescriptor file)
-             throws DescriptorValidationException {
-      final int dotpos = fullName.lastIndexOf('.');
-      final String name;
-      if (dotpos == -1) {
-        name = fullName;
-      } else {
-        addPackage(fullName.substring(0, dotpos), file);
-        name = fullName.substring(dotpos + 1);
-      }
-
-      final GenericDescriptor old =
-        descriptorsByName.put(fullName,
-          new PackageDescriptor(name, fullName, file));
-      if (old != null) {
-        descriptorsByName.put(fullName, old);
-        if (!(old instanceof PackageDescriptor)) {
-          throw new DescriptorValidationException(file,
-              '\"' + name + "\" is already defined (as something other than a "
-              + "package) in file \"" + old.getFile().getName() + "\".");
-        }
-      }
-    }
-
-    /** A (GenericDescriptor, int) pair, used as a map key. */
-    private static final class DescriptorIntPair {
-      private final GenericDescriptor descriptor;
-      private final int number;
-
-      DescriptorIntPair(final GenericDescriptor descriptor, final int number) {
-        this.descriptor = descriptor;
-        this.number = number;
-      }
-
-      @Override
-      public int hashCode() {
-        return descriptor.hashCode() * ((1 << 16) - 1) + number;
-      }
-      @Override
-      public boolean equals(final Object obj) {
-        if (!(obj instanceof DescriptorIntPair)) {
-          return false;
-        }
-        final DescriptorIntPair other = (DescriptorIntPair)obj;
-        return descriptor == other.descriptor && number == other.number;
-      }
-    }
-
-    /**
-     * Adds a field to the fieldsByNumber table.  Throws an exception if a
-     * field with the same containing type and number already exists.
-     */
-    void addFieldByNumber(final FieldDescri

<TRUNCATED>