PageRenderTime 45ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/java/src/main/java/com/google/protobuf/ExtensionRegistryLite.java

https://github.com/CyanogenMod/android_external_protobuf
Java | 169 lines | 73 code | 16 blank | 80 comment | 7 complexity | 262cb688b28accec2fb653ad397a38b4 MD5 | raw file
  1. // Protocol Buffers - Google's data interchange format
  2. // Copyright 2008 Google Inc. All rights reserved.
  3. // http://code.google.com/p/protobuf/
  4. //
  5. // Redistribution and use in source and binary forms, with or without
  6. // modification, are permitted provided that the following conditions are
  7. // met:
  8. //
  9. // * Redistributions of source code must retain the above copyright
  10. // notice, this list of conditions and the following disclaimer.
  11. // * Redistributions in binary form must reproduce the above
  12. // copyright notice, this list of conditions and the following disclaimer
  13. // in the documentation and/or other materials provided with the
  14. // distribution.
  15. // * Neither the name of Google Inc. nor the names of its
  16. // contributors may be used to endorse or promote products derived from
  17. // this software without specific prior written permission.
  18. //
  19. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  22. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  23. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  24. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  25. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  26. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  27. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  28. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  29. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30. package com.google.protobuf;
  31. import java.util.Collections;
  32. import java.util.HashMap;
  33. import java.util.Map;
  34. /**
  35. * Equivalent to {@link ExtensionRegistry} but supports only "lite" types.
  36. * <p>
  37. * If all of your types are lite types, then you only need to use
  38. * {@code ExtensionRegistryLite}. Similarly, if all your types are regular
  39. * types, then you only need {@link ExtensionRegistry}. Typically it does not
  40. * make sense to mix the two, since if you have any regular types in your
  41. * program, you then require the full runtime and lose all the benefits of
  42. * the lite runtime, so you might as well make all your types be regular types.
  43. * However, in some cases (e.g. when depending on multiple third-patry libraries
  44. * where one uses lite types and one uses regular), you may find yourself
  45. * wanting to mix the two. In this case things get more complicated.
  46. * <p>
  47. * There are three factors to consider: Whether the type being extended is
  48. * lite, whether the embedded type (in the case of a message-typed extension)
  49. * is lite, and whether the extension itself is lite. Since all three are
  50. * declared in different files, they could all be different. Here are all
  51. * the combinations and which type of registry to use:
  52. * <pre>
  53. * Extended type Inner type Extension Use registry
  54. * =======================================================================
  55. * lite lite lite ExtensionRegistryLite
  56. * lite regular lite ExtensionRegistry
  57. * regular regular regular ExtensionRegistry
  58. * all other combinations not supported
  59. * </pre>
  60. * <p>
  61. * Note that just as regular types are not allowed to contain lite-type fields,
  62. * they are also not allowed to contain lite-type extensions. This is because
  63. * regular types must be fully accessible via reflection, which in turn means
  64. * that all the inner messages must also support reflection. On the other hand,
  65. * since regular types implement the entire lite interface, there is no problem
  66. * with embedding regular types inside lite types.
  67. *
  68. * @author kenton@google.com Kenton Varda
  69. */
  70. public class ExtensionRegistryLite {
  71. /** Construct a new, empty instance. */
  72. public static ExtensionRegistryLite newInstance() {
  73. return new ExtensionRegistryLite();
  74. }
  75. /** Get the unmodifiable singleton empty instance. */
  76. public static ExtensionRegistryLite getEmptyRegistry() {
  77. return EMPTY;
  78. }
  79. /** Returns an unmodifiable view of the registry. */
  80. public ExtensionRegistryLite getUnmodifiable() {
  81. return new ExtensionRegistryLite(this);
  82. }
  83. /**
  84. * Find an extension by containing type and field number.
  85. *
  86. * @return Information about the extension if found, or {@code null}
  87. * otherwise.
  88. */
  89. @SuppressWarnings("unchecked")
  90. public <ContainingType extends MessageLite>
  91. GeneratedMessageLite.GeneratedExtension<ContainingType, ?>
  92. findLiteExtensionByNumber(
  93. final ContainingType containingTypeDefaultInstance,
  94. final int fieldNumber) {
  95. return (GeneratedMessageLite.GeneratedExtension<ContainingType, ?>)
  96. extensionsByNumber.get(
  97. new ObjectIntPair(containingTypeDefaultInstance, fieldNumber));
  98. }
  99. /** Add an extension from a lite generated file to the registry. */
  100. public final void add(
  101. final GeneratedMessageLite.GeneratedExtension<?, ?> extension) {
  102. extensionsByNumber.put(
  103. new ObjectIntPair(extension.getContainingTypeDefaultInstance(),
  104. extension.getNumber()),
  105. extension);
  106. }
  107. // =================================================================
  108. // Private stuff.
  109. // Constructors are package-private so that ExtensionRegistry can subclass
  110. // this.
  111. ExtensionRegistryLite() {
  112. this.extensionsByNumber =
  113. new HashMap<ObjectIntPair,
  114. GeneratedMessageLite.GeneratedExtension<?, ?>>();
  115. }
  116. ExtensionRegistryLite(ExtensionRegistryLite other) {
  117. if (other == EMPTY) {
  118. this.extensionsByNumber = Collections.emptyMap();
  119. } else {
  120. this.extensionsByNumber =
  121. Collections.unmodifiableMap(other.extensionsByNumber);
  122. }
  123. }
  124. private final Map<ObjectIntPair,
  125. GeneratedMessageLite.GeneratedExtension<?, ?>>
  126. extensionsByNumber;
  127. private ExtensionRegistryLite(boolean empty) {
  128. this.extensionsByNumber = Collections.emptyMap();
  129. }
  130. private static final ExtensionRegistryLite EMPTY =
  131. new ExtensionRegistryLite(true);
  132. /** A (Object, int) pair, used as a map key. */
  133. private static final class ObjectIntPair {
  134. private final Object object;
  135. private final int number;
  136. ObjectIntPair(final Object object, final int number) {
  137. this.object = object;
  138. this.number = number;
  139. }
  140. @Override
  141. public int hashCode() {
  142. return System.identityHashCode(object) * ((1 << 16) - 1) + number;
  143. }
  144. @Override
  145. public boolean equals(final Object obj) {
  146. if (!(obj instanceof ObjectIntPair)) {
  147. return false;
  148. }
  149. final ObjectIntPair other = (ObjectIntPair)obj;
  150. return object == other.object && number == other.number;
  151. }
  152. }
  153. }