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 |