Skip to content

Commit 7f360d3

Browse files
committed
2 parents e3375f2 + f1bd039 commit 7f360d3

File tree

76 files changed

+1861
-6335
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

76 files changed

+1861
-6335
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ local.properties
77
google-services.json
88
/build.gradle
99
_artifacts
10+
.DS_Store

buildSrc/build.gradle

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ repositories {
2323
}
2424
jcenter()
2525
mavenCentral()
26+
27+
maven {
28+
url 'https://storage.googleapis.com/android-ci/mvn/'
29+
}
2630
}
2731

2832
sourceSets {
@@ -44,6 +48,8 @@ dependencies {
4448
runtime 'io.opencensus:opencensus-impl:0.18.0'
4549
implementation group: 'com.google.code.gson', name: 'gson', version: '2.8.6'
4650

51+
implementation 'org.jetbrains.dokka:dokka-android-gradle-plugin:0.9.17-g004'
52+
4753
implementation 'com.android.tools.build:gradle:3.4.1'
4854
testImplementation 'junit:junit:4.12'
4955
testImplementation group: 'com.google.code.gson', name: 'gson', version: '2.8.6'

buildSrc/src/main/groovy/com/google/firebase/gradle/plugins/FirebaseLibraryPlugin.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ private static void setupApiInformationAnalysis(Project project, LibraryExtensio
157157

158158
task.setSourceSet(mainSourceSet);
159159
});
160+
project.getTasks().getByName("check").dependsOn(docStubs);
160161

161162
android
162163
.getLibraryVariants()

buildSrc/src/main/groovy/com/google/firebase/gradle/plugins/apiinfo/GenerateStubsTask.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ public void run() {
7070
spec.setArgs(
7171
Arrays.asList(
7272
getMetalavaJarPath(),
73-
"--quiet",
73+
"--no-banner",
7474
"--source-path",
7575
sourcePath,
7676
"--classpath",

buildSrc/src/main/groovy/com/google/firebase/gradle/plugins/ci/device/FirebaseTestServer.groovy

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import org.gradle.api.Project
2222

2323

2424
class FirebaseTestServer extends TestServer {
25-
private static final String DEFAULT_BUCKET_NAME = 'android-ci'
2625
final Project project
2726
final FirebaseTestLabExtension extension
2827
final Random random
@@ -68,7 +67,10 @@ class FirebaseTestServer extends TestServer {
6867
Optional<String> resultsBucket = Optional.ofNullable(System.getenv('FTL_RESULTS_BUCKET')).map(Environment.&expand)
6968
Optional<String> resultsDir = Optional.ofNullable(System.getenv('FTL_RESULTS_DIR')).map(Environment.&expand)
7069

71-
List<String> args = ['--results-bucket', resultsBucket.orElse(DEFAULT_BUCKET_NAME)]
70+
List<String> args = []
71+
if (resultsBucket.isPresent()) {
72+
args += ['--results-bucket', resultsBucket.get()]
73+
}
7274
if (resultsDir.isPresent()) {
7375
args += ['--results-dir', Paths.get(resultsDir.get(), "${project.path}_${random.nextLong()}")]
7476
}

buildSrc/src/main/groovy/com/google/firebase/gradle/plugins/publish/PublishingPlugin.groovy

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import com.google.firebase.gradle.plugins.FirebaseLibraryExtension
1818
import digital.wup.android_maven_publish.AndroidMavenPublishPlugin
1919
import org.gradle.api.Plugin
2020
import org.gradle.api.Project
21+
import org.gradle.api.UnknownProjectException
2122
import org.gradle.api.publish.maven.MavenPublication
2223
import org.gradle.api.tasks.bundling.Jar
2324
import org.gradle.api.tasks.bundling.Zip
@@ -154,6 +155,11 @@ class PublishingPlugin implements Plugin<Project> {
154155
buildMavenZip.mustRunAfter info
155156

156157
firebasePublish.dependsOn info, buildMavenZip
158+
159+
try {
160+
project.project(':kotlindoc')
161+
firebasePublish.dependsOn ':kotlindoc:dokkaFirebaseZip'
162+
} catch(UnknownProjectException e) {}
157163
}
158164
}
159165

docs/ktx/database.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ val myObject = snapshot.getValue<MyClass>()
7272
```kotlin
7373
val snapshot: DataSnapshot = ...
7474
val typeIndicator = object : GenericTypeIndicator<List<Message>>() {}
75-
val messages: List<Message> = snapshot.getValue(t)
75+
val messages: List<Message> = snapshot.getValue(typeIndicator)
7676
```
7777

7878
**Kotlin + KTX**

encoders/firebase-encoders-json/api.txt

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ package com.google.firebase.encoders {
2020
method @NonNull public com.google.firebase.encoders.ObjectEncoderContext add(@NonNull String, int) throws com.google.firebase.encoders.EncodingException, java.io.IOException;
2121
method @NonNull public com.google.firebase.encoders.ObjectEncoderContext add(@NonNull String, long) throws com.google.firebase.encoders.EncodingException, java.io.IOException;
2222
method @NonNull public com.google.firebase.encoders.ObjectEncoderContext add(@NonNull String, boolean) throws com.google.firebase.encoders.EncodingException, java.io.IOException;
23+
method @NonNull public com.google.firebase.encoders.ObjectEncoderContext inline(@Nullable Object) throws com.google.firebase.encoders.EncodingException, java.io.IOException;
2324
method @NonNull public com.google.firebase.encoders.ObjectEncoderContext nested(@NonNull String) throws java.io.IOException;
2425
}
2526

@@ -39,14 +40,15 @@ package com.google.firebase.encoders {
3940

4041
package com.google.firebase.encoders.annotations {
4142

42-
@java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface Encodable {
43+
@java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) public @interface Encodable {
4344
}
4445

45-
@java.lang.annotation.Target(java.lang.annotation.ElementType.METHOD) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public static @interface Encodable.Field {
46+
@java.lang.annotation.Target(java.lang.annotation.ElementType.METHOD) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) public static @interface Encodable.Field {
47+
method public abstract boolean inline() default false;
4648
method public abstract String name() default "";
4749
}
4850

49-
@java.lang.annotation.Target(java.lang.annotation.ElementType.METHOD) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public static @interface Encodable.Ignore {
51+
@java.lang.annotation.Target(java.lang.annotation.ElementType.METHOD) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) public static @interface Encodable.Ignore {
5052
}
5153

5254
}
@@ -72,6 +74,7 @@ package com.google.firebase.encoders.json {
7274
method @NonNull public com.google.firebase.encoders.json.JsonDataEncoderBuilder configureWith(@NonNull com.google.firebase.encoders.config.Configurator);
7375
method @NonNull public <T> com.google.firebase.encoders.json.JsonDataEncoderBuilder registerEncoder(@NonNull Class<T>, @NonNull com.google.firebase.encoders.ObjectEncoder<? super T>);
7476
method @NonNull public <T> com.google.firebase.encoders.json.JsonDataEncoderBuilder registerEncoder(@NonNull Class<T>, @NonNull com.google.firebase.encoders.ValueEncoder<? super T>);
77+
method @NonNull public com.google.firebase.encoders.json.JsonDataEncoderBuilder registerFallbackEncoder(@NonNull com.google.firebase.encoders.ObjectEncoder<java.lang.Object>);
7578
}
7679

7780
}

encoders/firebase-encoders-json/src/json/java/com/google/firebase/encoders/json/JsonDataEncoderBuilder.java

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
package com.google.firebase.encoders.json;
1616

1717
import androidx.annotation.NonNull;
18-
import androidx.annotation.Nullable;
1918
import com.google.firebase.encoders.DataEncoder;
2019
import com.google.firebase.encoders.EncodingException;
2120
import com.google.firebase.encoders.ObjectEncoder;
@@ -36,8 +35,15 @@
3635

3736
public final class JsonDataEncoderBuilder implements EncoderConfig<JsonDataEncoderBuilder> {
3837

38+
private final ObjectEncoder<Object> DEFAULT_FALLBACK_ENCODER =
39+
(o, ctx) -> {
40+
throw new EncodingException(
41+
"Couldn't find encoder for type " + o.getClass().getCanonicalName());
42+
};
43+
3944
private final Map<Class<?>, ObjectEncoder<?>> objectEncoders = new HashMap<>();
4045
private final Map<Class<?>, ValueEncoder<?>> valueEncoders = new HashMap<>();
46+
private ObjectEncoder<Object> fallbackEncoder = DEFAULT_FALLBACK_ENCODER;
4147

4248
private static final class TimestampEncoder implements ValueEncoder<Date> {
4349
private static final DateFormat rfc339;
@@ -48,7 +54,7 @@ private static final class TimestampEncoder implements ValueEncoder<Date> {
4854
}
4955

5056
@Override
51-
public void encode(@Nullable Date o, @NonNull ValueEncoderContext ctx)
57+
public void encode(@NonNull Date o, @NonNull ValueEncoderContext ctx)
5258
throws EncodingException, IOException {
5359
ctx.add(rfc339.format(o));
5460
}
@@ -84,6 +90,14 @@ public <T> JsonDataEncoderBuilder registerEncoder(
8490
return this;
8591
}
8692

93+
/** Encoder used if no encoders are found among explicitly registered ones. */
94+
@NonNull
95+
public JsonDataEncoderBuilder registerFallbackEncoder(
96+
@NonNull ObjectEncoder<Object> fallbackEncoder) {
97+
this.fallbackEncoder = fallbackEncoder;
98+
return this;
99+
}
100+
87101
@NonNull
88102
public JsonDataEncoderBuilder configureWith(@NonNull Configurator config) {
89103
config.configure(this);
@@ -97,8 +111,9 @@ public DataEncoder build() {
97111
public void encode(@NonNull Object o, @NonNull Writer writer)
98112
throws IOException, EncodingException {
99113
JsonValueObjectEncoderContext encoderContext =
100-
new JsonValueObjectEncoderContext(writer, objectEncoders, valueEncoders);
101-
encoderContext.add(o);
114+
new JsonValueObjectEncoderContext(
115+
writer, objectEncoders, valueEncoders, fallbackEncoder);
116+
encoderContext.add(o, false);
102117
encoderContext.close();
103118
}
104119

encoders/firebase-encoders-json/src/json/java/com/google/firebase/encoders/json/JsonValueObjectEncoderContext.java

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import java.io.IOException;
2727
import java.io.Writer;
2828
import java.util.Collection;
29+
import java.util.Date;
2930
import java.util.Map;
3031

3132
final class JsonValueObjectEncoderContext implements ObjectEncoderContext, ValueEncoderContext {
@@ -35,20 +36,24 @@ final class JsonValueObjectEncoderContext implements ObjectEncoderContext, Value
3536
private final JsonWriter jsonWriter;
3637
private final Map<Class<?>, ObjectEncoder<?>> objectEncoders;
3738
private final Map<Class<?>, ValueEncoder<?>> valueEncoders;
39+
private final ObjectEncoder<Object> fallbackEncoder;
3840

3941
JsonValueObjectEncoderContext(
4042
@NonNull Writer writer,
4143
@NonNull Map<Class<?>, ObjectEncoder<?>> objectEncoders,
42-
@NonNull Map<Class<?>, ValueEncoder<?>> valueEncoders) {
44+
@NonNull Map<Class<?>, ValueEncoder<?>> valueEncoders,
45+
ObjectEncoder<Object> fallbackEncoder) {
4346
this.jsonWriter = new JsonWriter(writer);
4447
this.objectEncoders = objectEncoders;
4548
this.valueEncoders = valueEncoders;
49+
this.fallbackEncoder = fallbackEncoder;
4650
}
4751

4852
private JsonValueObjectEncoderContext(JsonValueObjectEncoderContext anotherContext) {
4953
this.jsonWriter = anotherContext.jsonWriter;
5054
this.objectEncoders = anotherContext.objectEncoders;
5155
this.valueEncoders = anotherContext.valueEncoders;
56+
this.fallbackEncoder = anotherContext.fallbackEncoder;
5257
}
5358

5459
@NonNull
@@ -61,7 +66,7 @@ public JsonValueObjectEncoderContext add(@NonNull String name, @Nullable Object
6166
jsonWriter.nullValue();
6267
return this;
6368
}
64-
return add(o);
69+
return add(o, false);
6570
}
6671

6772
@NonNull
@@ -100,6 +105,12 @@ public JsonValueObjectEncoderContext add(@NonNull String name, boolean value)
100105
return add(value);
101106
}
102107

108+
@NonNull
109+
@Override
110+
public ObjectEncoderContext inline(@Nullable Object value) throws IOException, EncodingException {
111+
return add(value, true);
112+
}
113+
103114
@NonNull
104115
@Override
105116
public ObjectEncoderContext nested(@NonNull String name) throws IOException {
@@ -165,7 +176,12 @@ public JsonValueObjectEncoderContext add(@Nullable byte[] bytes)
165176
}
166177

167178
@NonNull
168-
JsonValueObjectEncoderContext add(@Nullable Object o) throws IOException, EncodingException {
179+
JsonValueObjectEncoderContext add(@Nullable Object o, boolean inline)
180+
throws IOException, EncodingException {
181+
if (inline && cannotBeInline(o)) {
182+
throw new EncodingException(
183+
String.format("%s cannot be encoded inline", o == null ? null : o.getClass()));
184+
}
169185
if (o == null) {
170186
jsonWriter.nullValue();
171187
return this;
@@ -201,12 +217,12 @@ JsonValueObjectEncoderContext add(@Nullable Object o) throws IOException, Encodi
201217
}
202218
} else if (o instanceof Number[]) {
203219
for (Number item : (Number[]) o) {
204-
add(item);
220+
add(item, false);
205221
}
206222

207223
} else {
208224
for (Object item : (Object[]) o) {
209-
add(item);
225+
add(item, false);
210226
}
211227
}
212228
jsonWriter.endArray();
@@ -216,7 +232,7 @@ JsonValueObjectEncoderContext add(@Nullable Object o) throws IOException, Encodi
216232
Collection collection = (Collection) o;
217233
jsonWriter.beginArray();
218234
for (Object elem : collection) {
219-
add(elem);
235+
add(elem, false);
220236
}
221237
jsonWriter.endArray();
222238
return this;
@@ -243,10 +259,7 @@ JsonValueObjectEncoderContext add(@Nullable Object o) throws IOException, Encodi
243259
@SuppressWarnings("unchecked") // safe because get the encoder by checking the object's type.
244260
ObjectEncoder<Object> objectEncoder = (ObjectEncoder<Object>) objectEncoders.get(o.getClass());
245261
if (objectEncoder != null) {
246-
jsonWriter.beginObject();
247-
objectEncoder.encode(o, this);
248-
jsonWriter.endObject();
249-
return this;
262+
return doEncode(objectEncoder, o, inline);
250263
}
251264
@SuppressWarnings("unchecked") // safe because get the encoder by checking the object's type.
252265
ValueEncoder<Object> valueEncoder = (ValueEncoder<Object>) valueEncoders.get(o.getClass());
@@ -261,8 +274,24 @@ JsonValueObjectEncoderContext add(@Nullable Object o) throws IOException, Encodi
261274
return this;
262275
}
263276

264-
throw new EncodingException(
265-
"Couldn't find encoder for type " + o.getClass().getCanonicalName());
277+
return doEncode(fallbackEncoder, o, inline);
278+
}
279+
280+
JsonValueObjectEncoderContext doEncode(ObjectEncoder<Object> encoder, Object o, boolean inline)
281+
throws IOException, EncodingException {
282+
if (!inline) jsonWriter.beginObject();
283+
encoder.encode(o, this);
284+
if (!inline) jsonWriter.endObject();
285+
return this;
286+
}
287+
288+
private boolean cannotBeInline(Object value) {
289+
return value == null
290+
|| value.getClass().isArray()
291+
|| value instanceof Collection
292+
|| value instanceof Date
293+
|| value instanceof Enum
294+
|| value instanceof Number;
266295
}
267296

268297
void close() throws IOException {

encoders/firebase-encoders-json/src/main/java/com/google/firebase/encoders/Encoder.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
package com.google.firebase.encoders;
1616

1717
import androidx.annotation.NonNull;
18-
import androidx.annotation.Nullable;
1918
import java.io.IOException;
2019

2120
/**
@@ -26,6 +25,5 @@
2625
interface Encoder<TValue, TContext> {
2726

2827
/** Encode {@code obj} using {@code TContext}. */
29-
void encode(@Nullable TValue obj, @NonNull TContext context)
30-
throws EncodingException, IOException;
28+
void encode(@NonNull TValue obj, @NonNull TContext context) throws EncodingException, IOException;
3129
}

encoders/firebase-encoders-json/src/main/java/com/google/firebase/encoders/ObjectEncoderContext.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,26 @@ ObjectEncoderContext add(@NonNull String name, double value)
6969
ObjectEncoderContext add(@NonNull String name, boolean value)
7070
throws IOException, EncodingException;
7171

72+
/**
73+
* Encodes a given object inline in current context.
74+
*
75+
* <p>For example:
76+
*
77+
* <pre>{@code
78+
* ctx.add("key", "value");
79+
* ctx.inline(new MyType());
80+
*
81+
* // produces the following object:
82+
* // {
83+
* // "key": "value",
84+
* // "myTypeField1": true,
85+
* // "myTypeField2": 1
86+
* // }
87+
* }</pre>
88+
*/
89+
@NonNull
90+
ObjectEncoderContext inline(@Nullable Object value) throws IOException, EncodingException;
91+
7292
/**
7393
* Begin a nested JSON object.
7494
*

encoders/firebase-encoders-json/src/main/java/com/google/firebase/encoders/annotations/Encodable.java

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,18 +42,26 @@
4242
* }<pre>
4343
*/
4444
@Target(ElementType.TYPE)
45-
@Retention(RetentionPolicy.CLASS)
45+
@Retention(RetentionPolicy.RUNTIME)
4646
public @interface Encodable {
4747

48-
/** Specifies a custom field name for a given property of a type. */
48+
/** Field configuration. */
4949
@Target(ElementType.METHOD)
50-
@Retention(RetentionPolicy.CLASS)
50+
@Retention(RetentionPolicy.RUNTIME)
5151
@interface Field {
52+
/** Specifies a custom field name for a given property of a type. */
5253
String name() default "";
54+
55+
/**
56+
* Mark a field to be encoded inline in the parent context, instead of nested under its own key.
57+
*
58+
* <p>Note: if a field is inlined, its name is ignored.
59+
*/
60+
boolean inline() default false;
5361
}
5462

5563
/** Indicates the code generator to ignore a given property of a type. */
5664
@Target(ElementType.METHOD)
57-
@Retention(RetentionPolicy.CLASS)
65+
@Retention(RetentionPolicy.RUNTIME)
5866
@interface Ignore {}
5967
}

0 commit comments

Comments
 (0)