| 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 | |
| 98 public static boolean isEagerlyParseMessageSets() { | 82 public static boolean isEagerlyParseMessageSets() { |
| 99 return eagerlyParseMessageSets; | 83 return eagerlyParseMessageSets; |
| 100 } | 84 } |
| 101 | 85 |
| 102 public static void setEagerlyParseMessageSets(boolean isEagerlyParse) { | 86 public static void setEagerlyParseMessageSets(boolean isEagerlyParse) { |
| 103 eagerlyParseMessageSets = isEagerlyParse; | 87 eagerlyParseMessageSets = isEagerlyParse; |
| 104 } | 88 } |
| 105 | 89 |
| 106 /** | 90 /** Construct a new, empty instance. */ |
| 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 */ | |
| 112 public static ExtensionRegistryLite newInstance() { | 91 public static ExtensionRegistryLite newInstance() { |
| 113 return ExtensionRegistryFactory.create(); | 92 return new ExtensionRegistryLite(); |
| 114 } | 93 } |
| 115 | 94 |
| 116 /** | 95 /** Get the unmodifiable singleton empty instance. */ |
| 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 */ | |
| 120 public static ExtensionRegistryLite getEmptyRegistry() { | 96 public static ExtensionRegistryLite getEmptyRegistry() { |
| 121 return ExtensionRegistryFactory.createEmpty(); | 97 return EMPTY; |
| 122 } | 98 } |
| 123 | 99 |
| 124 | |
| 125 /** Returns an unmodifiable view of the registry. */ | 100 /** Returns an unmodifiable view of the registry. */ |
| 126 public ExtensionRegistryLite getUnmodifiable() { | 101 public ExtensionRegistryLite getUnmodifiable() { |
| 127 return new ExtensionRegistryLite(this); | 102 return new ExtensionRegistryLite(this); |
| 128 } | 103 } |
| 129 | 104 |
| 130 /** | 105 /** |
| 131 * Find an extension by containing type and field number. | 106 * Find an extension by containing type and field number. |
| 132 * | 107 * |
| 133 * @return Information about the extension if found, or {@code null} | 108 * @return Information about the extension if found, or {@code null} |
| 134 * otherwise. | 109 * otherwise. |
| (...skipping 11 matching lines...) Expand all Loading... |
| 146 | 121 |
| 147 /** Add an extension from a lite generated file to the registry. */ | 122 /** Add an extension from a lite generated file to the registry. */ |
| 148 public final void add( | 123 public final void add( |
| 149 final GeneratedMessageLite.GeneratedExtension<?, ?> extension) { | 124 final GeneratedMessageLite.GeneratedExtension<?, ?> extension) { |
| 150 extensionsByNumber.put( | 125 extensionsByNumber.put( |
| 151 new ObjectIntPair(extension.getContainingTypeDefaultInstance(), | 126 new ObjectIntPair(extension.getContainingTypeDefaultInstance(), |
| 152 extension.getNumber()), | 127 extension.getNumber()), |
| 153 extension); | 128 extension); |
| 154 } | 129 } |
| 155 | 130 |
| 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 | |
| 173 // ================================================================= | 131 // ================================================================= |
| 174 // Private stuff. | 132 // Private stuff. |
| 175 | 133 |
| 176 // Constructors are package-private so that ExtensionRegistry can subclass | 134 // Constructors are package-private so that ExtensionRegistry can subclass |
| 177 // this. | 135 // this. |
| 178 | 136 |
| 179 ExtensionRegistryLite() { | 137 ExtensionRegistryLite() { |
| 180 this.extensionsByNumber = | 138 this.extensionsByNumber = |
| 181 new HashMap<ObjectIntPair, | 139 new HashMap<ObjectIntPair, |
| 182 GeneratedMessageLite.GeneratedExtension<?, ?>>(); | 140 GeneratedMessageLite.GeneratedExtension<?, ?>>(); |
| 183 } | 141 } |
| 184 static final ExtensionRegistryLite EMPTY_REGISTRY_LITE = | |
| 185 new ExtensionRegistryLite(true); | |
| 186 | 142 |
| 187 ExtensionRegistryLite(ExtensionRegistryLite other) { | 143 ExtensionRegistryLite(ExtensionRegistryLite other) { |
| 188 if (other == EMPTY_REGISTRY_LITE) { | 144 if (other == EMPTY) { |
| 189 this.extensionsByNumber = Collections.emptyMap(); | 145 this.extensionsByNumber = Collections.emptyMap(); |
| 190 } else { | 146 } else { |
| 191 this.extensionsByNumber = | 147 this.extensionsByNumber = |
| 192 Collections.unmodifiableMap(other.extensionsByNumber); | 148 Collections.unmodifiableMap(other.extensionsByNumber); |
| 193 } | 149 } |
| 194 } | 150 } |
| 195 | 151 |
| 196 private final Map<ObjectIntPair, | 152 private final Map<ObjectIntPair, |
| 197 GeneratedMessageLite.GeneratedExtension<?, ?>> | 153 GeneratedMessageLite.GeneratedExtension<?, ?>> |
| 198 extensionsByNumber; | 154 extensionsByNumber; |
| 199 | 155 |
| 200 ExtensionRegistryLite(boolean empty) { | 156 private ExtensionRegistryLite(boolean empty) { |
| 201 this.extensionsByNumber = Collections.emptyMap(); | 157 this.extensionsByNumber = Collections.emptyMap(); |
| 202 } | 158 } |
| 159 private static final ExtensionRegistryLite EMPTY = |
| 160 new ExtensionRegistryLite(true); |
| 203 | 161 |
| 204 /** A (Object, int) pair, used as a map key. */ | 162 /** A (Object, int) pair, used as a map key. */ |
| 205 private static final class ObjectIntPair { | 163 private static final class ObjectIntPair { |
| 206 private final Object object; | 164 private final Object object; |
| 207 private final int number; | 165 private final int number; |
| 208 | 166 |
| 209 ObjectIntPair(final Object object, final int number) { | 167 ObjectIntPair(final Object object, final int number) { |
| 210 this.object = object; | 168 this.object = object; |
| 211 this.number = number; | 169 this.number = number; |
| 212 } | 170 } |
| 213 | 171 |
| 214 @Override | 172 @Override |
| 215 public int hashCode() { | 173 public int hashCode() { |
| 216 return System.identityHashCode(object) * ((1 << 16) - 1) + number; | 174 return System.identityHashCode(object) * ((1 << 16) - 1) + number; |
| 217 } | 175 } |
| 218 @Override | 176 @Override |
| 219 public boolean equals(final Object obj) { | 177 public boolean equals(final Object obj) { |
| 220 if (!(obj instanceof ObjectIntPair)) { | 178 if (!(obj instanceof ObjectIntPair)) { |
| 221 return false; | 179 return false; |
| 222 } | 180 } |
| 223 final ObjectIntPair other = (ObjectIntPair)obj; | 181 final ObjectIntPair other = (ObjectIntPair)obj; |
| 224 return object == other.object && number == other.number; | 182 return object == other.object && number == other.number; |
| 225 } | 183 } |
| 226 } | 184 } |
| 227 } | 185 } |
| OLD | NEW |