| OLD | NEW |
| 1 // Protocol Buffers - Google's data interchange format | 1 // Protocol Buffers - Google's data interchange format |
| 2 // Copyright 2008 Google Inc. All rights reserved. | 2 // Copyright 2008 Google Inc. All rights reserved. |
| 3 // https://developers.google.com/protocol-buffers/ | 3 // https://developers.google.com/protocol-buffers/ |
| 4 // | 4 // |
| 5 // Redistribution and use in source and binary forms, with or without | 5 // Redistribution and use in source and binary forms, with or without |
| 6 // modification, are permitted provided that the following conditions are | 6 // modification, are permitted provided that the following conditions are |
| 7 // met: | 7 // met: |
| 8 // | 8 // |
| 9 // * Redistributions of source code must retain the above copyright | 9 // * Redistributions of source code must retain the above copyright |
| 10 // notice, this list of conditions and the following disclaimer. | 10 // notice, this list of conditions and the following disclaimer. |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 72 */ | 72 */ |
| 73 public class ExtensionRegistryLite { | 73 public class ExtensionRegistryLite { |
| 74 | 74 |
| 75 // Set true to enable lazy parsing feature for MessageSet. | 75 // Set true to enable lazy parsing feature for MessageSet. |
| 76 // | 76 // |
| 77 // TODO(xiangl): Now we use a global flag to control whether enable lazy | 77 // TODO(xiangl): Now we use a global flag to control whether enable lazy |
| 78 // parsing feature for MessageSet, which may be too crude for some | 78 // parsing feature for MessageSet, which may be too crude for some |
| 79 // applications. Need to support this feature on smaller granularity. | 79 // applications. Need to support this feature on smaller granularity. |
| 80 private static volatile boolean eagerlyParseMessageSets = false; | 80 private static volatile boolean eagerlyParseMessageSets = false; |
| 81 | 81 |
| 82 // Visible for testing. |
| 83 static final String EXTENSION_CLASS_NAME = "com.google.protobuf.Extension"; |
| 84 |
| 85 /* @Nullable */ |
| 86 static Class<?> resolveExtensionClass() { |
| 87 try { |
| 88 return Class.forName(EXTENSION_CLASS_NAME); |
| 89 } catch (ClassNotFoundException e) { |
| 90 // See comment in ExtensionRegistryFactory on the potential expense of thi
s. |
| 91 return null; |
| 92 } |
| 93 } |
| 94 |
| 95 /* @Nullable */ |
| 96 private static final Class<?> extensionClass = resolveExtensionClass(); |
| 97 |
| 82 public static boolean isEagerlyParseMessageSets() { | 98 public static boolean isEagerlyParseMessageSets() { |
| 83 return eagerlyParseMessageSets; | 99 return eagerlyParseMessageSets; |
| 84 } | 100 } |
| 85 | 101 |
| 86 public static void setEagerlyParseMessageSets(boolean isEagerlyParse) { | 102 public static void setEagerlyParseMessageSets(boolean isEagerlyParse) { |
| 87 eagerlyParseMessageSets = isEagerlyParse; | 103 eagerlyParseMessageSets = isEagerlyParse; |
| 88 } | 104 } |
| 89 | 105 |
| 90 /** Construct a new, empty instance. */ | 106 /** |
| 107 * Construct a new, empty instance. |
| 108 * |
| 109 * <p>This may be an {@code ExtensionRegistry} if the full (non-Lite) proto li
braries are |
| 110 * available. |
| 111 */ |
| 91 public static ExtensionRegistryLite newInstance() { | 112 public static ExtensionRegistryLite newInstance() { |
| 92 return new ExtensionRegistryLite(); | 113 return ExtensionRegistryFactory.create(); |
| 93 } | 114 } |
| 94 | 115 |
| 95 /** Get the unmodifiable singleton empty instance. */ | 116 /** |
| 117 * Get the unmodifiable singleton empty instance of either ExtensionRegistryLi
te or |
| 118 * {@code ExtensionRegistry} (if the full (non-Lite) proto libraries are avail
able). |
| 119 */ |
| 96 public static ExtensionRegistryLite getEmptyRegistry() { | 120 public static ExtensionRegistryLite getEmptyRegistry() { |
| 97 return EMPTY; | 121 return ExtensionRegistryFactory.createEmpty(); |
| 98 } | 122 } |
| 99 | 123 |
| 124 |
| 100 /** Returns an unmodifiable view of the registry. */ | 125 /** Returns an unmodifiable view of the registry. */ |
| 101 public ExtensionRegistryLite getUnmodifiable() { | 126 public ExtensionRegistryLite getUnmodifiable() { |
| 102 return new ExtensionRegistryLite(this); | 127 return new ExtensionRegistryLite(this); |
| 103 } | 128 } |
| 104 | 129 |
| 105 /** | 130 /** |
| 106 * Find an extension by containing type and field number. | 131 * Find an extension by containing type and field number. |
| 107 * | 132 * |
| 108 * @return Information about the extension if found, or {@code null} | 133 * @return Information about the extension if found, or {@code null} |
| 109 * otherwise. | 134 * otherwise. |
| (...skipping 11 matching lines...) Expand all Loading... |
| 121 | 146 |
| 122 /** Add an extension from a lite generated file to the registry. */ | 147 /** Add an extension from a lite generated file to the registry. */ |
| 123 public final void add( | 148 public final void add( |
| 124 final GeneratedMessageLite.GeneratedExtension<?, ?> extension) { | 149 final GeneratedMessageLite.GeneratedExtension<?, ?> extension) { |
| 125 extensionsByNumber.put( | 150 extensionsByNumber.put( |
| 126 new ObjectIntPair(extension.getContainingTypeDefaultInstance(), | 151 new ObjectIntPair(extension.getContainingTypeDefaultInstance(), |
| 127 extension.getNumber()), | 152 extension.getNumber()), |
| 128 extension); | 153 extension); |
| 129 } | 154 } |
| 130 | 155 |
| 156 /** |
| 157 * Add an extension from a lite generated file to the registry only if it is |
| 158 * a non-lite extension i.e. {@link GeneratedMessageLite.GeneratedExtension}.
*/ |
| 159 public final void add(ExtensionLite<?, ?> extension) { |
| 160 if (GeneratedMessageLite.GeneratedExtension.class.isAssignableFrom(extension
.getClass())) { |
| 161 add((GeneratedMessageLite.GeneratedExtension<?, ?>) extension); |
| 162 } |
| 163 if (ExtensionRegistryFactory.isFullRegistry(this)) { |
| 164 try { |
| 165 this.getClass().getMethod("add", extensionClass).invoke(this, extension)
; |
| 166 } catch (Exception e) { |
| 167 throw new IllegalArgumentException( |
| 168 String.format("Could not invoke ExtensionRegistry#add for %s", exten
sion), e); |
| 169 } |
| 170 } |
| 171 } |
| 172 |
| 131 // ================================================================= | 173 // ================================================================= |
| 132 // Private stuff. | 174 // Private stuff. |
| 133 | 175 |
| 134 // Constructors are package-private so that ExtensionRegistry can subclass | 176 // Constructors are package-private so that ExtensionRegistry can subclass |
| 135 // this. | 177 // this. |
| 136 | 178 |
| 137 ExtensionRegistryLite() { | 179 ExtensionRegistryLite() { |
| 138 this.extensionsByNumber = | 180 this.extensionsByNumber = |
| 139 new HashMap<ObjectIntPair, | 181 new HashMap<ObjectIntPair, |
| 140 GeneratedMessageLite.GeneratedExtension<?, ?>>(); | 182 GeneratedMessageLite.GeneratedExtension<?, ?>>(); |
| 141 } | 183 } |
| 184 static final ExtensionRegistryLite EMPTY_REGISTRY_LITE = |
| 185 new ExtensionRegistryLite(true); |
| 142 | 186 |
| 143 ExtensionRegistryLite(ExtensionRegistryLite other) { | 187 ExtensionRegistryLite(ExtensionRegistryLite other) { |
| 144 if (other == EMPTY) { | 188 if (other == EMPTY_REGISTRY_LITE) { |
| 145 this.extensionsByNumber = Collections.emptyMap(); | 189 this.extensionsByNumber = Collections.emptyMap(); |
| 146 } else { | 190 } else { |
| 147 this.extensionsByNumber = | 191 this.extensionsByNumber = |
| 148 Collections.unmodifiableMap(other.extensionsByNumber); | 192 Collections.unmodifiableMap(other.extensionsByNumber); |
| 149 } | 193 } |
| 150 } | 194 } |
| 151 | 195 |
| 152 private final Map<ObjectIntPair, | 196 private final Map<ObjectIntPair, |
| 153 GeneratedMessageLite.GeneratedExtension<?, ?>> | 197 GeneratedMessageLite.GeneratedExtension<?, ?>> |
| 154 extensionsByNumber; | 198 extensionsByNumber; |
| 155 | 199 |
| 156 private ExtensionRegistryLite(boolean empty) { | 200 ExtensionRegistryLite(boolean empty) { |
| 157 this.extensionsByNumber = Collections.emptyMap(); | 201 this.extensionsByNumber = Collections.emptyMap(); |
| 158 } | 202 } |
| 159 private static final ExtensionRegistryLite EMPTY = | |
| 160 new ExtensionRegistryLite(true); | |
| 161 | 203 |
| 162 /** A (Object, int) pair, used as a map key. */ | 204 /** A (Object, int) pair, used as a map key. */ |
| 163 private static final class ObjectIntPair { | 205 private static final class ObjectIntPair { |
| 164 private final Object object; | 206 private final Object object; |
| 165 private final int number; | 207 private final int number; |
| 166 | 208 |
| 167 ObjectIntPair(final Object object, final int number) { | 209 ObjectIntPair(final Object object, final int number) { |
| 168 this.object = object; | 210 this.object = object; |
| 169 this.number = number; | 211 this.number = number; |
| 170 } | 212 } |
| 171 | 213 |
| 172 @Override | 214 @Override |
| 173 public int hashCode() { | 215 public int hashCode() { |
| 174 return System.identityHashCode(object) * ((1 << 16) - 1) + number; | 216 return System.identityHashCode(object) * ((1 << 16) - 1) + number; |
| 175 } | 217 } |
| 176 @Override | 218 @Override |
| 177 public boolean equals(final Object obj) { | 219 public boolean equals(final Object obj) { |
| 178 if (!(obj instanceof ObjectIntPair)) { | 220 if (!(obj instanceof ObjectIntPair)) { |
| 179 return false; | 221 return false; |
| 180 } | 222 } |
| 181 final ObjectIntPair other = (ObjectIntPair)obj; | 223 final ObjectIntPair other = (ObjectIntPair)obj; |
| 182 return object == other.object && number == other.number; | 224 return object == other.object && number == other.number; |
| 183 } | 225 } |
| 184 } | 226 } |
| 185 } | 227 } |
| OLD | NEW |