├── .bazelversion ├── .bcr └── source.template.json ├── MODULE.bazel ├── java └── jsinterop │ └── annotations │ ├── BUILD │ ├── JsPackage.java │ ├── JsIgnore.java │ ├── JsNonNull.java │ ├── JsNullable.java │ ├── JsAsync.java │ ├── JsOptional.java │ ├── JsConstructor.java │ ├── JsMethod.java │ ├── JsFunction.java │ ├── JsOverlay.java │ ├── JsProperty.java │ ├── JsType.java │ └── JsEnum.java ├── BUILD ├── .github └── workflows │ ├── release_prep.sh │ ├── scorecard.yaml │ ├── ci.yaml │ └── release.yaml ├── CONTRIBUTING.md ├── .bazelrc ├── maven ├── pom-annotations.xml ├── publish_to_sonatype.sh ├── build_section.xml └── deploy.sh ├── README.md └── LICENSE /.bazelversion: -------------------------------------------------------------------------------- 1 | 8.3.1 -------------------------------------------------------------------------------- /.bcr/source.template.json: -------------------------------------------------------------------------------- 1 | { 2 | "integrity": "", 3 | "strip_prefix": "{REPO}-{VERSION}", 4 | "url": "https://github.com/{OWNER}/{REPO}/releases/download/{TAG}/{REPO}-{TAG}.tar.gz" 5 | } 6 | -------------------------------------------------------------------------------- /MODULE.bazel: -------------------------------------------------------------------------------- 1 | module(name = "jsinterop_annotations") 2 | 3 | bazel_dep(name = "bazel_skylib", version = "1.7.1") 4 | bazel_dep(name = "google_bazel_common", version = "0.0.1") 5 | bazel_dep(name = "rules_java", version = "8.13.0") 6 | bazel_dep(name = "rules_license", version = "1.0.0") 7 | 8 | # Bump the rules_python version to workaround https://github.com/bazel-contrib/rules_python/issues/1169 9 | bazel_dep(name = "rules_python", version = "1.4.1") 10 | -------------------------------------------------------------------------------- /java/jsinterop/annotations/BUILD: -------------------------------------------------------------------------------- 1 | # Description: 2 | # Jsinterop Annotations for J2CL/GWT 3 | # 4 | 5 | load("@google_bazel_common//tools/javadoc:javadoc.bzl", "javadoc_library") 6 | load("@rules_java//java:defs.bzl", "java_library") 7 | 8 | package( 9 | default_applicable_licenses = ["//:license"], 10 | default_visibility = ["//:__pkg__"], 11 | ) 12 | 13 | licenses(["notice"]) 14 | 15 | java_library( 16 | name = "annotations", 17 | srcs = glob(["*.java"]), 18 | # Keep compatibility with Java 11 for open source GWT. 19 | javacopts = ["-source 11 -target 11"], 20 | ) 21 | 22 | javadoc_library( 23 | name = "annotations-javadoc", 24 | srcs = glob(["*.java"]), 25 | tags = [ 26 | "manual", 27 | "notap", 28 | ], 29 | ) 30 | -------------------------------------------------------------------------------- /BUILD: -------------------------------------------------------------------------------- 1 | # Description: 2 | # Jsinterop Annotations for J2CL/GWT 3 | # 4 | 5 | load("@bazel_skylib//rules:build_test.bzl", "build_test") 6 | load("@rules_license//rules:license.bzl", "license") 7 | 8 | package( 9 | default_applicable_licenses = [":license"], 10 | default_visibility = [ 11 | "//third_party/java/jsinterop_annotations:__subpackages__", 12 | "@j2cl//:__subpackages__", 13 | ], 14 | licenses = ["notice"], 15 | ) 16 | 17 | license( 18 | name = "license", 19 | package_name = "jsinterop_annotations", 20 | ) 21 | 22 | exports_files(["LICENSE"]) 23 | 24 | build_test( 25 | name = "rule_test", 26 | targets = [ 27 | ":jsinterop-annotations", 28 | ], 29 | ) 30 | 31 | alias( 32 | name = "jsinterop-annotations", 33 | actual = "//java/jsinterop/annotations:annotations", 34 | tags = ["avoid_dep"], # Use //third_party/java/jsinterop_annotations:jsinterop-annotations instead. 35 | ) 36 | -------------------------------------------------------------------------------- /.github/workflows/release_prep.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # This file is used to prepare the githubrelease. 3 | # It is not intended to be run directly but called from the github release 4 | # workflow: bazel-contrib/.github/workflows/release_ruleset.yaml\ 5 | set -euo pipefail 6 | 7 | tag="$1" 8 | # GITHUB_REPOSITORY looks like user/repository_name, let strip the user part. 9 | repository=${GITHUB_REPOSITORY#*/} 10 | # The prefix is used to determine the directory structure of the archive. We 11 | # strip the 'v'prefix from the version number. 12 | directory="${repository}-${tag#v}" 13 | archive="${repository}-${tag}.tar.gz" 14 | 15 | git archive --format="tar.gz" --prefix=${directory}/ -o "${archive}" ${tag} 16 | 17 | # Replace hyphens with underscores in the repository name to match our Bazel 18 | # module naming conventions. 19 | bazel_module_name="${repository//-/_}" 20 | # The stdout of this program will be used as the top of the release notes for 21 | # this release. 22 | cat << EOF 23 | ## Using Bazel 8 or later, add to your \`MODULE.bazel\` file: 24 | 25 | \`\`\`starlark 26 | bazel_dep(name = "${bazel_module_name}", version = "${tag}") 27 | \`\`\` 28 | EOF -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to Contribute 2 | 3 | We'd love to accept your patches and contributions to this project. There are 4 | just a few small guidelines you need to follow. 5 | 6 | ## Contributor License Agreement 7 | 8 | Contributions to this project must be accompanied by a Contributor License 9 | Agreement. You (or your employer) retain the copyright to your contribution; 10 | this simply gives us permission to use and redistribute your contributions as 11 | part of the project. Head over to to see 12 | your current agreements on file or to sign a new one. 13 | 14 | You generally only need to submit a CLA once, so if you've already submitted one 15 | (even if it was for a different project), you probably don't need to do it 16 | again. 17 | 18 | ## Code reviews 19 | 20 | All submissions, including submissions by project members, require review. We 21 | use GitHub pull requests for this purpose. Consult 22 | [GitHub Help](https://help.github.com/articles/about-pull-requests/) for more 23 | information on using pull requests. 24 | 25 | ## Community Guidelines 26 | 27 | This project follows 28 | [Google's Open Source Community Guidelines](https://opensource.google.com/conduct/). 29 | -------------------------------------------------------------------------------- /java/jsinterop/annotations/JsPackage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | package jsinterop.annotations; 17 | 18 | import java.lang.annotation.Documented; 19 | import java.lang.annotation.ElementType; 20 | import java.lang.annotation.Retention; 21 | import java.lang.annotation.RetentionPolicy; 22 | import java.lang.annotation.Target; 23 | 24 | /** 25 | * Provides a default namespace for all @JsType classes in a package by applying to 26 | * 'package-info.java'. 27 | */ 28 | @Retention(RetentionPolicy.RUNTIME) 29 | @Target(ElementType.PACKAGE) 30 | @Documented 31 | public @interface JsPackage { 32 | /** Namespace of the global JavaScript object. */ 33 | String GLOBAL = ""; 34 | 35 | String namespace(); 36 | } 37 | -------------------------------------------------------------------------------- /.bazelrc: -------------------------------------------------------------------------------- 1 | # Recommended bazel settings for working with J2CL. 2 | # You can copy this into root of your workspace. 3 | 4 | build --watchfs 5 | 6 | build --spawn_strategy=local 7 | 8 | build --strategy=J2cl=worker 9 | build --strategy=J2clStrip=worker 10 | build --strategy=J2clRta=worker 11 | 12 | build --strategy=J2wasm=worker 13 | build --strategy=J2wasmStrip=worker 14 | build --strategy=J2wasmApp=local 15 | 16 | build --strategy=Closure=worker 17 | build --strategy=Javac=worker 18 | build --strategy=JavaIjar=local 19 | build --strategy=JavaDeployJar=local 20 | build --strategy=JavaSourceJar=local 21 | build --strategy=Turbine=local 22 | 23 | # --experimental_inprocess_symlink_creation is used to workaround the missing 24 | # support for paths with spaces https://github.com/bazelbuild/bazel/issues/4327. 25 | # Remove the two flags after this issue is fixed in bazel new release. 26 | build --enable_platform_specific_config 27 | build:macos --experimental_inprocess_symlink_creation 28 | 29 | test --test_output=errors 30 | 31 | # Enable Java 21. Note this doesn't control whether J2CL accepts Java 21 inputs, 32 | # that is controlled in build_defs/internal_do_not_use/j2cl_common.bzl. 33 | build --java_language_version=21 34 | build --java_runtime_version=21 35 | 36 | # Enable Java 21 for J2CL compiler itself 37 | build --tool_java_language_version=21 38 | build --tool_java_runtime_version=21 -------------------------------------------------------------------------------- /java/jsinterop/annotations/JsIgnore.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | package jsinterop.annotations; 17 | 18 | import java.lang.annotation.Documented; 19 | import java.lang.annotation.ElementType; 20 | import java.lang.annotation.Retention; 21 | import java.lang.annotation.RetentionPolicy; 22 | import java.lang.annotation.Target; 23 | 24 | /** 25 | * Marks a member to be ignored for JsInterop purposes. 26 | * 27 | *

This is particularly useful when {@link JsType} is applied to a class and some members need to 28 | * be ignored as they don't comply with restrictions (e.g. overloading) or shouldn't be exported for 29 | * other reasons. 30 | */ 31 | @Retention(RetentionPolicy.RUNTIME) 32 | @Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.FIELD}) 33 | @Documented 34 | public @interface JsIgnore {} 35 | -------------------------------------------------------------------------------- /java/jsinterop/annotations/JsNonNull.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | package jsinterop.annotations; 17 | 18 | import java.lang.annotation.Documented; 19 | import java.lang.annotation.ElementType; 20 | import java.lang.annotation.Retention; 21 | import java.lang.annotation.RetentionPolicy; 22 | import java.lang.annotation.Target; 23 | 24 | /** 25 | * JsNonNull marks a type as non-nullable indicating that program elements of such a type can not 26 | * hold a {@code null} value. 27 | * 28 | *

Note that JsNonNull can only be used in a JsConstructor, a JsMethod, a JsProperty or a 29 | * JsFunction method. 30 | * 31 | *

This annotation is informational in the GWT compiler but other compilers or tools might use it 32 | * for example to annotate types in the output JavaScript program. 33 | */ 34 | @Retention(RetentionPolicy.RUNTIME) 35 | @Target(ElementType.TYPE_USE) 36 | @Documented 37 | public @interface JsNonNull {} 38 | -------------------------------------------------------------------------------- /java/jsinterop/annotations/JsNullable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | package jsinterop.annotations; 17 | 18 | import java.lang.annotation.Documented; 19 | import java.lang.annotation.ElementType; 20 | import java.lang.annotation.Retention; 21 | import java.lang.annotation.RetentionPolicy; 22 | import java.lang.annotation.Target; 23 | 24 | /** 25 | * JsNullable marks a type variable as nullable indicating that program elements of such a type can 26 | * hold a {@code null} value. 27 | * 28 | *

Note that JsNullable can only be used on type variables in the context of a JsConstructor, a 29 | * JsMethod, a JsProperty or a JsFunction method. 30 | * 31 | *

This annotation is informational in the GWT compiler but other compilers or tools might use it 32 | * for example to annotate types in the output JavaScript program. 33 | */ 34 | @Retention(RetentionPolicy.RUNTIME) 35 | @Target(ElementType.TYPE_USE) 36 | @Documented 37 | public @interface JsNullable {} 38 | -------------------------------------------------------------------------------- /java/jsinterop/annotations/JsAsync.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | package jsinterop.annotations; 17 | 18 | import java.lang.annotation.Documented; 19 | import java.lang.annotation.ElementType; 20 | import java.lang.annotation.Retention; 21 | import java.lang.annotation.RetentionPolicy; 22 | import java.lang.annotation.Target; 23 | 24 | /** 25 | * JsAsync marks a method to be transpiled to an async JavaScript method. 26 | * 27 | *

Adding this annotation to a method adds an {@code async} keyword to the generated JavaScript 28 | * function. 29 | * 30 | *

There are some limitations apply on JsAsync to make the annotation practical: 31 | * 32 | *

36 | * 37 | *

This is an EXPERIMENTAL annotation and only works in J2CL. 38 | */ 39 | @Retention(RetentionPolicy.RUNTIME) 40 | @Target(ElementType.METHOD) 41 | @Documented 42 | public @interface JsAsync {} 43 | -------------------------------------------------------------------------------- /java/jsinterop/annotations/JsOptional.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | package jsinterop.annotations; 17 | 18 | import java.lang.annotation.Documented; 19 | import java.lang.annotation.ElementType; 20 | import java.lang.annotation.Retention; 21 | import java.lang.annotation.RetentionPolicy; 22 | import java.lang.annotation.Target; 23 | 24 | /** 25 | * JsOptional marks a parameter in a method as optional indicating that the argument can be omitted 26 | * from the function call when called from JavaScript side. 27 | * 28 | *

Note that JsOptional can only be used in a JsConstructor, a JsMethod or a JsFunction method. 29 | * An optional argument cannot precede a non-optional argument (a vararg is considered an optional 30 | * argument). 31 | * 32 | *

This annotation is informational in the GWT compiler but other compilers or tools might use it 33 | * for example to annotate types in the output JavaScript program. 34 | */ 35 | @Retention(RetentionPolicy.RUNTIME) 36 | @Target(ElementType.PARAMETER) 37 | @Documented 38 | public @interface JsOptional {} 39 | -------------------------------------------------------------------------------- /java/jsinterop/annotations/JsConstructor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | package jsinterop.annotations; 17 | 18 | import java.lang.annotation.Documented; 19 | import java.lang.annotation.ElementType; 20 | import java.lang.annotation.Retention; 21 | import java.lang.annotation.RetentionPolicy; 22 | import java.lang.annotation.Target; 23 | 24 | /** 25 | * JsConstructor marks a constructor that will be translated into a JavaScript constructor function. 26 | * 27 | *

Due to ES6 class semantics, for non-native JsTypes only one JsConstructor is allowed to exist 28 | * in the type which becomes the 'primary constructor'. All other constructors in the type must 29 | * delegate to it. Subclasses of a type with JsConstructor should follow the same restriction with 30 | * the exception that the primary constructor is not required to be marked as JsConstructor but 31 | * still need to delegate to super primary constructor. 32 | */ 33 | @Retention(RetentionPolicy.RUNTIME) 34 | @Target(ElementType.CONSTRUCTOR) 35 | @Documented 36 | public @interface JsConstructor {} 37 | -------------------------------------------------------------------------------- /maven/pom-annotations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | com.google.jsinterop 6 | jsinterop-annotations 7 | __VERSION__ 8 | 9 | JsInterop Annotations 10 | JsInterop Annotations contains a set of java annotations that drive the javascript 11 | code generation of J2CL transpiler or GWT 12 | https://github.com/google/jsinterop-annotations 13 | 14 | 15 | 16 | The Apache Software License, Version 2.0 17 | http://www.apache.org/licenses/LICENSE-2.0.txt 18 | repo 19 | 20 | 21 | 22 | 23 | scm:git:https://github.com/google/jsinterop-annotations.git 24 | scm:git:git@github.com:google/jsinterop-annotations.git 25 | https://github.com/google/jsinterop-annotations 26 | 27 | 28 | 29 | https://github.com/google/jsinterop-annotations/issues 30 | GitHub Issues 31 | 32 | 33 | 34 | 35 | J2CL team 36 | Google 37 | http://www.google.com 38 | 39 | 40 | __BUILD_SECTION__ 41 | 42 | -------------------------------------------------------------------------------- /java/jsinterop/annotations/JsMethod.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | package jsinterop.annotations; 17 | 18 | import java.lang.annotation.Documented; 19 | import java.lang.annotation.ElementType; 20 | import java.lang.annotation.Retention; 21 | import java.lang.annotation.RetentionPolicy; 22 | import java.lang.annotation.Target; 23 | 24 | /** 25 | * JsMethod marks a method that will be directly translated into a JavaScript method preserving its 26 | * name. 27 | * 28 | *

Note: In JavaScript, instance members are defined on the prototype and class members are 29 | * defined on the constructor function of the type. 30 | */ 31 | @Retention(RetentionPolicy.RUNTIME) 32 | @Target(ElementType.METHOD) 33 | @Documented 34 | public @interface JsMethod { 35 | 36 | /** 37 | * Customizes the name of the member in generated JavaScript. If not provided, the Java name will 38 | * be used. 39 | */ 40 | String name() default ""; 41 | 42 | /** 43 | * Customizes the namespace of the static member in generated JavaScript. If none is provided, 44 | * namespace is the enclosing class' fully qualified JavaScript name. 45 | */ 46 | String namespace() default ""; 47 | } 48 | -------------------------------------------------------------------------------- /java/jsinterop/annotations/JsFunction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | package jsinterop.annotations; 17 | 18 | import java.lang.annotation.Documented; 19 | import java.lang.annotation.ElementType; 20 | import java.lang.annotation.Retention; 21 | import java.lang.annotation.RetentionPolicy; 22 | import java.lang.annotation.Target; 23 | 24 | /** 25 | * JsFunction marks a functional interface as being the definition of a JavaScript function. 26 | * 27 | *

There are some limitations exists on JsFunction to make them practical and efficient: 28 | * 29 | *

37 | * 38 | *

As a best practice, we also recommend marking JsFunction interfaces with FunctionalInterface 39 | * to get improved checking in IDEs. 40 | * 41 | *

Instanceof and Castability: 42 | * 43 | *

Instanceof and casting for JsFunction is effectively a JavaScript {@code typeof} check to 44 | * determine if the instance is a function. 45 | */ 46 | @Retention(RetentionPolicy.RUNTIME) 47 | @Target(ElementType.TYPE) 48 | @Documented 49 | public @interface JsFunction {} 50 | -------------------------------------------------------------------------------- /java/jsinterop/annotations/JsOverlay.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | package jsinterop.annotations; 17 | 18 | import java.lang.annotation.Documented; 19 | import java.lang.annotation.ElementType; 20 | import java.lang.annotation.Retention; 21 | import java.lang.annotation.RetentionPolicy; 22 | import java.lang.annotation.Target; 23 | 24 | /** 25 | * JsOverlay is used to enhance Java API of the native JsTypes and JsFunctions so richer and more 26 | * Java friendly abstractions could be provided. 27 | * 28 | *

29 |  * {@literal @}JsType(isNative=true)
30 |  * class Person {
31 |  *   {@literal @}JsOverlay
32 |  *   private static final Person NO_BODY = new Person();
33 |  *
34 |  *   private String name;
35 |  *   private String lastName;
36 |  *
37 |  *   {@literal @}JsOverlay
38 |  *   public String getFullName() {
39 |  *     return (name + " " + lastName).trim();
40 |  *   }
41 |  * }
42 | * 43 | *

Note that: 44 | * 45 | *

50 | * 51 | * These restrictions are in place to avoid polymorphism because underneath the original type is not 52 | * modified and the overlay fields/methods are simply turned into static dispatches. 53 | */ 54 | @Retention(RetentionPolicy.RUNTIME) 55 | @Target({ElementType.METHOD, ElementType.FIELD}) 56 | @Documented 57 | public @interface JsOverlay {} 58 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # JsInterop Annotations · ![Latest Release](https://img.shields.io/github/v/release/google/jsinterop-annotations) · [![Build Status](https://github.com/google/jsinterop-annotations/actions/workflows/ci.yaml/badge.svg)](https://github.com/google/jsinterop-annotations/actions/workflows/ci.yaml) 2 | 3 | 4 | 5 | JsInterop Annotations contains a set of java annotations that drive the 6 | javascript code generation of [J2CL transpiler](https://github.com/google/j2cl) 7 | or [GWT](https://github.com/gwtproject/gwt) 8 | 9 | Bazel dependency 10 | ---------------- 11 | If your project uses [Bazel](https://bazel.build), J2CL repository already 12 | provides targets `@j2cl//:jsinterop-annotations` and 13 | `@j2cl://jsinterop-annotations-j2cl` for Server/Android and J2CL respectively. 14 | 15 | Maven dependency 16 | ---------------- 17 | If your project uses [Maven](https://maven.apache.org), add the following maven 18 | dependency in your `pom.xml`. Replace `RELEASE_VERSION` with an actual 19 | [release version](https://github.com/google/jsinterop-annotations/releases): 20 | 21 | 22 | com.google.jsinterop 23 | jsinterop-annotations 24 | RELEASE_VERSION 25 | 26 | 27 | Build GWT compatible maven jar files 28 | ------------------------------------ 29 | If you want to build the last version on your own, follow the instructions 30 | below: 31 | 32 | - Install [Bazelisk](https://github.com/bazelbuild/bazelisk): 33 | 34 | ```shell 35 | $ npm install -g @bazel/bazelisk 36 | $ alias bazel=bazelisk 37 | ``` 38 | - Clone this git repository: 39 | ```shell 40 | $ git clone https://github.com/google/jsinterop-annotations.git 41 | ``` 42 | - Run the release script: 43 | ```shell 44 | $ cd jsinterop-annotations 45 | $ ./maven/release_jsinterop_annotations.sh --version local --no-deploy 46 | ``` 47 | 48 | The script will output the directory containing the generated jar files that 49 | can be used with maven. 50 | 51 | Contributing 52 | ------------ 53 | Please refer to [the contributing document](CONTRIBUTING.md). 54 | 55 | Licensing 56 | --------- 57 | Please refer to [the license file](LICENSE). 58 | 59 | Disclaimer 60 | ---------- 61 | This is not an official Google product. 62 | 63 | -------------------------------------------------------------------------------- /maven/publish_to_sonatype.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright 2019 Google Inc. All Rights Reserved 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS-IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # The script generates the open source artifacts for JsInterop Annotations and 17 | # uploads them to sonatype. 18 | set -euo pipefail 19 | 20 | source "$(dirname "$0")/deploy.sh" 21 | 22 | readonly MAVEN_ARTIFACT="jsinterop-annotations" 23 | readonly BAZEL_ARTIFACT="annotations" 24 | readonly BAZEL_PATH="java/jsinterop/annotations" 25 | readonly COPY_SRCS_IN_JAR=false 26 | 27 | usage() { 28 | echo "" 29 | echo "$(basename $0): Build and deploy script for Jsinterop Annotations." 30 | echo "" 31 | echo "$(basename $0) --version [--no-deploy]" 32 | echo " --help" 33 | echo " Print this help output and exit." 34 | echo " --version " 35 | echo " Maven version of the library to use for deploying to sonatype." 36 | echo " --no-deploy" 37 | echo " Skip the deployment part but build all artifacts." 38 | echo " --sonatype-auto-publish" 39 | echo " Publish automatically the artifact on sonatype." 40 | echo "" 41 | } 42 | 43 | parse_arguments() { 44 | deploy_to_sonatype=true 45 | lib_version="" 46 | sonatype_auto_publish=false 47 | 48 | while [[ $# -gt 0 ]]; do 49 | case "$1" in 50 | --version ) 51 | shift 52 | lib_version=$1 53 | ;; 54 | --no-deploy ) 55 | deploy_to_sonatype=false 56 | ;; 57 | --help ) 58 | usage 59 | exit 0 60 | ;; 61 | --sonatype-auto-publish) 62 | sonatype_auto_publish=true 63 | ;; 64 | * ) 65 | common::error "unexpected option $1" 66 | ;; 67 | esac 68 | shift 69 | done 70 | } 71 | 72 | main() { 73 | parse_arguments "$@" 74 | 75 | common::check_version_set 76 | common::check_bazel_prerequisites 77 | common::check_maven_prerequisites 78 | 79 | common::build 80 | common::deploy_to_sonatype 81 | } 82 | 83 | # Set the trap to cleanup temporary files on EXIT 84 | trap common::cleanup_temp_files EXIT 85 | 86 | main "$@" 87 | -------------------------------------------------------------------------------- /java/jsinterop/annotations/JsProperty.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | package jsinterop.annotations; 17 | 18 | import java.lang.annotation.Documented; 19 | import java.lang.annotation.ElementType; 20 | import java.lang.annotation.Retention; 21 | import java.lang.annotation.RetentionPolicy; 22 | import java.lang.annotation.Target; 23 | 24 | /** 25 | * JsProperty marks a field or method that is translated directly into a JavaScript property 26 | * preserving its name. 27 | * 28 | *

If it is applied to a method, it will be treated as a property accessor. As a result, instead 29 | * of translating method calls to JsProperty methods as method calls in JS, they will be translated 30 | * as property lookups. When a JsProperty method implemented by a Java class, such methods will be 31 | * generated as property accessor in JavaScript, hence the property access will trigger the 32 | * execution of the matching getter or setter methods. 33 | * 34 | *

JsProperty follows JavaBean style naming convention to extract the default property name. If 35 | * the JavaBean convention is not followed, the name should be set explicitly. For example: 36 | * 37 | *

    38 | *
  • {@code @JsProperty getX()} or {@code @JsProperty isX()} translates as {@code this.x} 39 | *
  • {@code @JsProperty setX(int y)} translates as {@code this.x=y} 40 | *
41 | * 42 | *

Note: In JavaScript, instance members are defined on the prototype and class members are 43 | * defined on the constructor function of the type which mimics ES6 class style. 44 | */ 45 | @Retention(RetentionPolicy.RUNTIME) 46 | @Target({ElementType.METHOD, ElementType.FIELD}) 47 | @Documented 48 | public @interface JsProperty { 49 | 50 | /** 51 | * Customizes the name of the member in generated JavaScript. If none is provided; 52 | * 53 | *

    54 | *
  • if it is field, the simple Java name will be used. 55 | *
  • if it is a method, the name will be generated based on JavaBean conventions. 56 | *
57 | */ 58 | String name() default ""; 59 | 60 | /** 61 | * Customizes the namespace of the static member in generated JavaScript. If none is provided, 62 | * namespace is the enclosing class' fully qualified JavaScript name. 63 | */ 64 | String namespace() default ""; 65 | } 66 | -------------------------------------------------------------------------------- /maven/build_section.xml: -------------------------------------------------------------------------------- 1 | 2 | ${project.artifactId}-classes 3 | ${project.artifactId}-javadoc.jar 4 | ${project.artifactId}-sources.jar 5 | 6 | 7 | 8 | 9 | 10 | org.apache.maven.plugins 11 | maven-jar-plugin 12 | 3.4.2 13 | 14 | ${classesDirectory} 15 | 16 | 17 | 18 | org.codehaus.plexus 19 | plexus-io 20 | 21 | 3.5.1 22 | 23 | 24 | 25 | 26 | org.codehaus.mojo 27 | build-helper-maven-plugin 28 | 1.9.1 29 | 30 | 31 | attach-artifacts 32 | package 33 | 34 | attach-artifact 35 | 36 | 37 | 38 | 39 | ${javadocFile} 40 | jar 41 | javadoc 42 | 43 | 44 | ${sourcesFile} 45 | jar 46 | sources 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | org.apache.maven.plugins 55 | maven-gpg-plugin 56 | 3.2.7 57 | 58 | 59 | sign-artifacts 60 | verify 61 | 62 | sign 63 | 64 | 65 | 66 | 67 | 68 | org.sonatype.central 69 | central-publishing-maven-plugin 70 | 0.8.0 71 | true 72 | 73 | central 74 | ${autoPublish} 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /java/jsinterop/annotations/JsType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | package jsinterop.annotations; 17 | 18 | import java.lang.annotation.Documented; 19 | import java.lang.annotation.ElementType; 20 | import java.lang.annotation.Retention; 21 | import java.lang.annotation.RetentionPolicy; 22 | import java.lang.annotation.Target; 23 | 24 | /** 25 | * JsType is used to describe the JavaScript API of an object, either one that already exists from 26 | * the external JavaScript environment, or one that will be accessible from the external JavaScript 27 | * environment. 28 | * 29 | *

Marking an object with JsType is similar to marking each public member of the class with 30 | * {@link JsProperty}/{@link JsMethod}/{@link JsConstructor} respectively. In order for this to work 31 | * correctly the JavaScript name needs to be unique for each member. Some unobvious ways to cause 32 | * name collisions are: 33 | * 34 | *

    35 | *
  • having method or constructor overloads 36 | *
  • using the same name for a method and a field 37 | *
  • shadowing a field from parent 38 | *
39 | * 40 | *

Name collisions must be avoided by providing custom names (e.g. {@link JsProperty#name}) or by 41 | * ignoring members using {@link JsIgnore}. 42 | * 43 | *

If the JsType is marked as "native" via {@link #isNative}, then the type is considered a stub 44 | * for an existing class that is available in native JavaScript. Unlike non-native JsTypes, all 45 | * members are considered {@link JsProperty}/{@link JsMethod}/{@link JsConstructor} unless they are 46 | * explicitly marked with {@link JsOverlay}. 47 | * 48 | *

For native interfaces with no particular JavaScript type associated with them (e.g. structural 49 | * types) it is recommended to use {@code namespace = JsPackage.GLOBAL} and {@code name = '?'}. 50 | * 51 | *

Instanceof and Castability: 52 | * 53 | *

If the JsType is native, the generated code will try to mimic Javascript semantics. 54 | * 55 | *

All non-native JsTypes will follow regular Java semantics in terms of castability. 56 | * 57 | *

    58 | *
  • For concrete native JsTypes, cast checks and instanceof checks will be delegated to the 59 | * native JavaScript instanceof operator. 60 | *
  • For interface native JsTypes, instanceof is forbidden and casts to them always succeed. 61 | *
62 | */ 63 | @Retention(RetentionPolicy.RUNTIME) 64 | @Target(ElementType.TYPE) 65 | @Documented 66 | public @interface JsType { 67 | 68 | /** 69 | * Customizes the name of the type in generated JavaScript. If not provided, the simple Java name 70 | * will be used. 71 | */ 72 | String name() default ""; 73 | 74 | /** Customizes the namespace of the type in generated JavaScript. */ 75 | String namespace() default ""; 76 | 77 | /** Set to {@code true}, this JsType is a native JavaScript type. */ 78 | boolean isNative() default false; 79 | } 80 | -------------------------------------------------------------------------------- /java/jsinterop/annotations/JsEnum.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | package jsinterop.annotations; 17 | 18 | import java.lang.annotation.Documented; 19 | import java.lang.annotation.ElementType; 20 | import java.lang.annotation.Retention; 21 | import java.lang.annotation.RetentionPolicy; 22 | import java.lang.annotation.Target; 23 | 24 | /** 25 | * JsEnum marks a Java enum as being represented as a Closure enum, either one that already exists 26 | * from the external JavaScript environment, or one that will be accessible from the external 27 | * JavaScript environment. 28 | * 29 | *

The underlying type of the Closure enum can be specified via {@link #hasCustomValue} and 30 | * declaring an instance field named "value" of the desired type. 31 | * 32 | *

If the JsEnum is non-native and has custom values, a constructor is required to allow 33 | * specifying the values for the enum constants, as in the following example 34 | * 35 | *


36 |  *  {@literal @}JsEnum(hasCustomValue=true)
37 |  *   enum IntJsEnum {
38 |  *     TEN(10),
39 |  *     TWENTY(20);
40 |  *
41 |  *     int value;
42 |  *
43 |  *     IntJsEnum(int value) { this.value = value; }
44 |  *   }
45 |  * 
46 | * 47 | *

If the JsEnum is native and has custom values, the value field is still required but 48 | * constructors are not needed nor allowed. 49 | * 50 | *

JsEnums do not support the full Java semantics: 51 | * 52 | *

    53 | *
  • No instance fields are allowed other than {@code value}, 54 | *
  • {@link Enum#name()} and {@code values()} are not supported. 55 | *
  • {@link Enum#ordinal()} is supported only for non-native JsEnums that don't have custom 56 | * values. 57 | *
  • The class is initialization might be delayed until a static field/method is accessed. 58 | *
59 | * 60 | *

The JavaScript namespace and name can be specified in a manner similar to JsTypes via {@link 61 | * #namespace} and {@link #name} respectively. 62 | * 63 | *

Methods and fields declared in the JsEnum are only accessible in Java code. Only the enum 64 | * constants are accessible from JavaScript code. 65 | * 66 | *

This annotation is only supported by J2CL. 67 | */ 68 | @Retention(RetentionPolicy.RUNTIME) 69 | @Target(ElementType.TYPE) 70 | @Documented 71 | public @interface JsEnum { 72 | 73 | /** 74 | * Customizes the name of the type in generated JavaScript. If not provided, the simple Java name 75 | * will be used. 76 | */ 77 | String name() default ""; 78 | 79 | /** Customizes the namespace of the type in generated JavaScript. */ 80 | String namespace() default ""; 81 | 82 | /** When set to {@code true}, this JsEnum is a native Closure enum type. */ 83 | boolean isNative() default false; 84 | 85 | /** 86 | * When set to {@code true}, this JsEnum will have a custom value defined by a field named 87 | * 'value'. The only allowed types for the value field are String and primitive types with the 88 | * exception of long. 89 | */ 90 | boolean hasCustomValue() default false; 91 | } 92 | -------------------------------------------------------------------------------- /.github/workflows/scorecard.yaml: -------------------------------------------------------------------------------- 1 | # This workflow uses actions that are not certified by GitHub. They are provided 2 | # by a third-party and are governed by separate terms of service, privacy 3 | # policy, and support documentation. 4 | 5 | name: Scorecard supply-chain security 6 | on: 7 | # For Branch-Protection check. Only the default branch is supported. See 8 | # https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection 9 | branch_protection_rule: 10 | # To guarantee Maintained check is occasionally updated. See 11 | # https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained 12 | schedule: 13 | - cron: '25 5 * * 5' 14 | push: 15 | branches: [ "master" ] 16 | 17 | # Declare default permissions as read only. 18 | permissions: read-all 19 | 20 | jobs: 21 | analysis: 22 | name: Scorecard analysis 23 | runs-on: ubuntu-latest 24 | # `publish_results: true` only works when run from the default branch. conditional can be removed if disabled. 25 | if: github.event.repository.default_branch == github.ref_name || github.event_name == 'pull_request' 26 | permissions: 27 | # Needed to upload the results to code-scanning dashboard. 28 | security-events: write 29 | # Needed to publish results and get a badge (see publish_results below). 30 | id-token: write 31 | # Uncomment the permissions below if installing in a private repository. 32 | # contents: read 33 | # actions: read 34 | 35 | steps: 36 | - name: "Checkout code" 37 | uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 38 | with: 39 | persist-credentials: false 40 | 41 | - name: "Run analysis" 42 | uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3 43 | with: 44 | results_file: results.sarif 45 | results_format: sarif 46 | # (Optional) "write" PAT token. Uncomment the `repo_token` line below if: 47 | # - you want to enable the Branch-Protection check on a *public* repository, or 48 | # - you are installing Scorecard on a *private* repository 49 | # To create the PAT, follow the steps in https://github.com/ossf/scorecard-action?tab=readme-ov-file#authentication-with-fine-grained-pat-optional. 50 | # repo_token: ${{ secrets.SCORECARD_TOKEN }} 51 | 52 | # Public repositories: 53 | # - Publish results to OpenSSF REST API for easy access by consumers 54 | # - Allows the repository to include the Scorecard badge. 55 | # - See https://github.com/ossf/scorecard-action#publishing-results. 56 | # For private repositories: 57 | # - `publish_results` will always be set to `false`, regardless 58 | # of the value entered here. 59 | publish_results: true 60 | 61 | # (Optional) Uncomment file_mode if you have a .gitattributes with files marked export-ignore 62 | # file_mode: git 63 | 64 | # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF 65 | # format to the repository Actions tab. 66 | - name: "Upload artifact" 67 | uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 68 | with: 69 | name: SARIF file 70 | path: results.sarif 71 | retention-days: 5 72 | 73 | # Upload the results to GitHub's code scanning dashboard (optional). 74 | # Commenting out will disable upload of results to your repo's Code Scanning dashboard 75 | - name: "Upload to code-scanning" 76 | uses: github/codeql-action/upload-sarif@v4 77 | with: 78 | sarif_file: results.sarif 79 | -------------------------------------------------------------------------------- /.github/workflows/ci.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2020 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # https://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Format reference: https://docs.github.com/en/actions/reference 16 | 17 | name: CI 18 | 19 | permissions: 20 | contents: read 21 | 22 | # https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#on 23 | on: 24 | push: 25 | branches: [ master ] 26 | pull_request: 27 | branches: [ master ] 28 | schedule: 29 | # Daily at 12pm UTC 30 | - cron: '0 12 * * *' 31 | # Can be called from other workflow to run the tests 32 | workflow_call: 33 | inputs: 34 | git_ref: 35 | description: 'The git ref used to checkout the repository and run the tests.' 36 | type: string 37 | required: false 38 | 39 | # https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobs 40 | jobs: 41 | build: 42 | strategy: 43 | fail-fast: false 44 | matrix: 45 | test-target: ['default', 'samples'] 46 | os: [macos-latest, ubuntu-latest] 47 | 48 | runs-on: ${{ matrix.os }} 49 | 50 | steps: 51 | - name: Setup Java 52 | uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # v5.0.0 53 | with: 54 | java-version: '21' 55 | distribution: 'zulu' 56 | java-package: jdk 57 | 58 | - name: Checkout the repository 59 | uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 60 | with: 61 | ref: ${{ inputs.git_ref || github.ref }} 62 | 63 | - name: Cache Bazel repositories 64 | uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 65 | with: 66 | path: ~/bazel-repository-cache 67 | key: bazel-repositories-${{hashFiles('**/MODULE.bazel')}} 68 | restore-keys: | 69 | bazel-repositories- 70 | 71 | - name: Cache Bazel results 72 | uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 73 | with: 74 | path: ~/bazel-action-cache 75 | key: bazel-actions-${{runner.os}}-${{github.sha}} 76 | restore-keys: | 77 | bazel-actions-${{runner.os}}- 78 | 79 | - name: Configure bazel 80 | run: | 81 | echo "build --repository_cache=~/bazel-repository-cache" >> ~/.bazelrc 82 | echo "build --disk_cache=~/bazel-action-cache" >> ~/.bazelrc 83 | echo "build -c opt" >> ~/.bazelrc 84 | echo "build --verbose_failures" >> ~/.bazelrc 85 | bazel info 86 | 87 | # Fake the host name to cause name lookups fail and fallback to localhost in WTL: 88 | # rules_webtesting/go/httphelper/http_helper.go#FQDN() 89 | # This prevents potential 'underscore' in resolved name which later used by 90 | # WebDriver that inherits a JDK bug (https://bugs.openjdk.org/browse/JDK-8221675). 91 | - name: Fake host name 92 | if: matrix.os == 'macos-latest' 93 | run: sudo scutil --set HostName unknown 94 | 95 | - name: Run tests 96 | if: matrix.test-target == 'default' 97 | run: ./build_test.sh CI 98 | - name: Run samples tests 99 | if: matrix.test-target == 'samples' 100 | run: | 101 | if [[ -f "./build_test_samples.sh" ]]; then 102 | ./build_test_samples.sh CI 103 | fi -------------------------------------------------------------------------------- /.github/workflows/release.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2025 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # https://www.apache.0rg/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | name: Release Project 15 | 16 | permissions: 17 | contents: read 18 | 19 | # TODO(b/452391493): Consider triggering the workflow on git release creation instead. 20 | # This workflow is triggered manually from the Actions tab. 21 | on: 22 | workflow_dispatch: 23 | inputs: 24 | version: 25 | description: 'The version to release' 26 | required: true 27 | type: string 28 | base_rc_version: 29 | description: 'The base RC version to use to create the final release. Should be formatted as X.Y.Z-RC.N' 30 | type: string 31 | required: false 32 | continue_if_tag_exists: 33 | description: 'Continue the workflow even if the GitHub tag already exists' 34 | type: boolean 35 | required: true 36 | default: false 37 | 38 | jobs: 39 | validate_inputs: 40 | runs-on: ubuntu-latest 41 | steps: 42 | - name: Validate base_rc_version 43 | run: | 44 | base_rc_version="${{ github.event.inputs.base_rc_version }}" 45 | if [[ -z "$base_rc_version" ]]; then 46 | echo "The base RC version field is empty, no validation needed." 47 | exit 0 48 | fi 49 | 50 | version="${{ github.event.inputs.version }}" 51 | repo_name="${{ github.event.repository.name }}" 52 | RC_REGEX='^([0-9]+\.[0-9]+\.[0-9]+)-RC\.?[0-9]+$' 53 | VERSION_REGEX='^[0-9]+\.[0-9]+\.[0-9]+$' 54 | 55 | # Ensure base_rc_version is not set for repositories that do not use RC versions. 56 | if [[ "$repo_name" == "jsinterop-generator" || "$repo_name" == "j2cl" ]]; then 57 | echo "Error: The base RC version field should not be set for repository '${repo_name}'." 58 | exit 1 59 | fi 60 | 61 | # Ensure base_rc_version is not set for for RC releases. 62 | # RC releases should not be based on another RC version. 63 | if [[ "$version" =~ $RC_REGEX ]]; then 64 | echo "Error: If the version '${version}' is an RC version, the base RC version field must be empty." 65 | exit 1 66 | fi 67 | 68 | # Validate base_rc_version format 69 | if [[ ! "$base_rc_version" =~ $RC_REGEX ]]; then 70 | echo "Error: Invalid base_rc_version format. Expected X.Y.Z-RC.N, but got '${base_rc_version}'." 71 | exit 1 72 | fi 73 | 74 | # Extract the base version from base_rc_version using the first captured group from the regex match. 75 | base_version_from_rc="${BASH_REMATCH[1]}" 76 | # Ensure the base version extracted from `base_rc_version` matches the intended release `version`. 77 | # This prevents releasing a final version based on an incorrect Release Candidate. 78 | if [[ "$base_version_from_rc" != "$version" ]]; then 79 | echo "Error: The base_rc_version '${base_rc_version}' does not match the version '${version}'." 80 | exit 1 81 | fi 82 | 83 | # Check if the base version is an existing git tag 84 | if ! git ls-remote ${{ github.server_url }}/${{ github.repository }} "refs/tags/${base_rc_version}" | grep -q "refs/tags/${base_rc_version}"; then 85 | echo "Error: The base version '${base_rc_version}' is not a valid tag in the repository." 86 | exit 1 87 | fi 88 | 89 | release: 90 | needs: validate_inputs 91 | uses: google/j2cl/.github/workflows/release_common.yaml@master 92 | 93 | permissions: 94 | # Permissions for creating a github release. 95 | contents: write 96 | # Permissions for publishing to bcr. 97 | id-token: write 98 | attestations: write 99 | 100 | # Pass the inputs from the manual trigger to the reusable workflow. 101 | with: 102 | version: ${{ github.event.inputs.version }} 103 | git_ref: ${{ github.event.inputs.base_rc_version && format('refs/tags/{0}', github.event.inputs.base_rc_version) || github.ref }} 104 | publish_to_sonatype: ${{ github.event.repository.name != 'jsinterop-generator' && github.event.repository.name != 'j2cl' }} 105 | continue_if_tag_exists: ${{ github.event.inputs.continue_if_tag_exists == 'true' }} 106 | publish_to_bcr: ${{ github.event.repository.name != 'jsinterop-annotations' }} 107 | 108 | # Allow the reusable workflow to access the secrets. 109 | secrets: inherit 110 | -------------------------------------------------------------------------------- /maven/deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright 2019 Google Inc. All Rights Reserved 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS-IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # 17 | # The script generates the open source artifacts needed for uploading a library to oss sonatype. 18 | # The artifacts include the jar file, the sources jar file and the javadoc jar file. 19 | # The script signs each jar and uploads them to sonatype. 20 | # 21 | # You need to install maven (3.0.5) before to run this script: 22 | # sudo apt-get install maven 23 | # 24 | # For using the gpg maven plugin, you need to create a gpg2 key. 25 | # 1) install gpg2 (1.4.16) if needed: 26 | # sudo apt-get install gnupg2 27 | # 2) create a key pair by running: 28 | # gpg2 --gen-key 29 | # 30 | # The script will ask you the passphrase of your key if the MAVEN_GPG_PASSPHRASE 31 | # environment variable is not set. 32 | # 33 | # You have to also configure the repository credentials by creating a settings.xml 34 | # file in the ~/.m2/ directory and add this section : 35 | # 36 | # 37 | # central 38 | # central_portal_token_username 39 | # central_portal_token_password 40 | # 41 | # 42 | # 43 | # You can find the repository credentials in go/valentine 44 | # 45 | readonly BAZEL_ROOT=$(pwd) 46 | readonly BUILD_SECTION_FILE="${BAZEL_ROOT}/maven/build_section.xml" 47 | 48 | common::error() { 49 | echo "Error: $@" >&2 50 | exit 1 51 | } 52 | 53 | common::info() { 54 | echo "Info: $@" 55 | } 56 | 57 | ####################################### 58 | # Check if : 59 | # - Bazel is installed, 60 | # - the script is run from the root of the Bazel repository. 61 | # - Bazel environment variables are set. 62 | # Globals: 63 | # BAZEL 64 | # BAZEL_ARTIFACT 65 | # BAZEL_PATH 66 | ####################################### 67 | common::check_bazel_prerequisites() { 68 | if [ ! -f "MODULE.bazel" ]; then 69 | common::error "This script must be run from the root of the Bazel repository (where MODULE.bazel exists)." 70 | fi 71 | 72 | # Check for Bazel or Bazelisk 73 | if command -v bazelisk &> /dev/null; then 74 | BAZEL="bazelisk" 75 | elif command -v bazel &> /dev/null; then 76 | BAZEL="bazel" 77 | else 78 | common::error "Neither Bazel nor Bazelisk is installed or in your PATH." 79 | fi 80 | 81 | if [[ -z "${BAZEL_ARTIFACT:-}" ]]; then 82 | common::error "BAZEL_ARTIFACT is not set." 83 | fi 84 | 85 | if [[ -z "${BAZEL_PATH:-}" ]]; then 86 | common::error "BAZEL_PATH is not set." 87 | fi 88 | } 89 | 90 | ####################################### 91 | # Check if : 92 | # - Maven is installed. 93 | # - MAVEN_ARTIFACT is set. 94 | # - a pom xml file is present in the maven directory 95 | # - global variables used for deployement are set. 96 | # Globals: 97 | # MAVEN_ARTIFACT 98 | # BAZEL_ROOT 99 | ####################################### 100 | common::check_maven_prerequisites() { 101 | if ! command -v mvn &> /dev/null; then 102 | common::error "Maven is not installed. Please install it." 103 | fi 104 | 105 | if [[ -z "${MAVEN_ARTIFACT:-}" ]]; then 106 | common::error "MAVEN_ARTIFACT is not set." 107 | fi 108 | 109 | # TODO(dramaix): Rename the pom files by using the maven artifact name. 110 | if [ ! -f "${BAZEL_ROOT}/maven/pom-${BAZEL_ARTIFACT}.xml" ]; then 111 | common::error "Maven pom file not found for artifact ${MAVEN_ARTIFACT}." 112 | fi 113 | 114 | if [[ -n "${COMMON_DEPENDENCIES_FILE:-}" ]] && [[ ! -f "${COMMON_DEPENDENCIES_FILE}" ]]; then 115 | common::error "COMMON_DEPENDENCIES_FILE is set but the file '${COMMON_DEPENDENCIES_FILE}' does not exist." 116 | fi 117 | 118 | # Every project that deploy to sonatype with maven needs to set the 119 | # deploy_to_sonatype variable to be able to skip the deployment step. 120 | if [[ -z "${deploy_to_sonatype:-}" ]]; then 121 | common::error "deploy_to_sonatype variable is missing." 122 | fi 123 | 124 | # sonatype_auto_publish is used to automatically publish the artifacts after 125 | # deployment. 126 | if [[ -z "${sonatype_auto_publish:-}" ]]; then 127 | common::error "sonatype_auto_publish variable is missing." 128 | fi 129 | } 130 | 131 | ####################################### 132 | # Check if --version flag is set and the value is valid. 133 | # Every project requires a version number for deployment. 134 | ####################################### 135 | common::check_version_set() { 136 | if [[ -z "$lib_version" ]]; then 137 | common::error "--version flag is missing" 138 | fi 139 | if [[ "$lib_version" == "--"* ]]; then 140 | common::error "Incorrect version value: $lib_version" 141 | fi 142 | } 143 | 144 | common::_bazel_build() { 145 | local target="$1" 146 | common::info "Building Bazel target: ${target}" 147 | "${BAZEL}" build "${target}" 148 | } 149 | 150 | common::build() { 151 | common::_bazel_build "//${BAZEL_PATH}:lib${BAZEL_ARTIFACT}.jar" 152 | common::_bazel_build "//${BAZEL_PATH}:lib${BAZEL_ARTIFACT}-src.jar" 153 | common::_bazel_build "//${BAZEL_PATH}:${BAZEL_ARTIFACT}-javadoc.jar" 154 | } 155 | 156 | common::_prepare_sources_artifact() { 157 | local maven_src_jar="$1" 158 | local bazel_src_jar="${BAZEL_ROOT}/bazel-bin/${BAZEL_PATH}/lib${BAZEL_ARTIFACT}-src.jar" 159 | 160 | if [[ -n "${LICENSE_HEADER_FILE:-}" ]]; then 161 | common::info "Adding license header to java source files." 162 | 163 | local srcs_directory=$(mktemp -d) 164 | (cd "${srcs_directory}" && jar xf "${bazel_src_jar}") 165 | 166 | local tmp_file=$(mktemp) 167 | 168 | for java in $(find "${srcs_directory}" -name '*.java'); do 169 | cat "${LICENSE_HEADER_FILE}" "${java}" > "${tmp_file}" 170 | mv "${tmp_file}" "${java}" 171 | done 172 | 173 | jar cf "${maven_src_jar}" -C "${srcs_directory}" . 174 | rm -rf "${srcs_directory}" 175 | else 176 | common::info "Copy sources jar to maven directory." 177 | cp "${bazel_src_jar}" "${maven_src_jar}" 178 | fi 179 | } 180 | 181 | common::_prepare_javadoc_artifact() { 182 | common::info "Copying javadoc jar to maven directory." 183 | local javadoc_jar="${BAZEL_ROOT}/bazel-bin/${BAZEL_PATH}/${BAZEL_ARTIFACT}-javadoc.jar" 184 | local maven_javadoc_jar="${maven_wd}/${MAVEN_ARTIFACT}-javadoc.jar" 185 | cp "${javadoc_jar}" "${maven_javadoc_jar}" 186 | } 187 | 188 | common::_extract_classes(){ 189 | common::info "Extracting class files to maven directory." 190 | local maven_src_jar="$1" 191 | 192 | local classes_directory="${maven_wd}/${MAVEN_ARTIFACT}-classes" 193 | mkdir -p "${classes_directory}" 194 | 195 | local bazel_jar_file="${BAZEL_ROOT}/bazel-bin/${BAZEL_PATH}/lib${BAZEL_ARTIFACT}.jar" 196 | 197 | (cd "${classes_directory}" && jar xf "${bazel_jar_file}") 198 | 199 | if [[ "${COPY_SRCS_IN_JAR:-true}" == true ]]; then 200 | common::info "Extracting sources along with the class files." 201 | (cd "${classes_directory}" && jar xf "${maven_src_jar}") 202 | fi 203 | } 204 | 205 | common::_prepare_pom_file() { 206 | common::info "Generating pom file for ${MAVEN_ARTIFACT}." 207 | # Replace placeholders and generate the final pom.xml 208 | local -a sed_args 209 | sed_args+=(-e "s/__VERSION__/${lib_version}/g") 210 | sed_args+=(-e "/__BUILD_SECTION__/r ${BUILD_SECTION_FILE}") 211 | sed_args+=(-e "/__BUILD_SECTION__/d") 212 | 213 | if [[ -n "${COMMON_DEPENDENCIES_FILE:-}" ]]; then 214 | common::info "Adding common dependencies to pom file." 215 | sed_args+=(-e "/__COMMON_DEPENDENCIES__/r ${COMMON_DEPENDENCIES_FILE}") 216 | sed_args+=(-e "/__COMMON_DEPENDENCIES__/d") 217 | fi 218 | 219 | sed "${sed_args[@]}" \ 220 | "${BAZEL_ROOT}/maven/pom-${BAZEL_ARTIFACT}.xml" > "${maven_wd}/pom-${MAVEN_ARTIFACT}.xml" 221 | } 222 | 223 | common::_prepare_artifact_for_sonatype() { 224 | local maven_src_jar="${maven_wd}/${MAVEN_ARTIFACT}-sources.jar" 225 | 226 | common::_prepare_sources_artifact "${maven_src_jar}" 227 | common::_prepare_javadoc_artifact 228 | # Extract the class files, maven will repackage everything in its own jar. 229 | common::_extract_classes "${maven_src_jar}" 230 | common::_prepare_pom_file 231 | } 232 | 233 | common::deploy_to_sonatype() { 234 | # TODO(Dramaix): Let the caller pass in the maven directory and be responsible 235 | # for setting the trap to cleanup the tmp directory 236 | if [[ -n "${1:-}" ]]; then 237 | common::info "Using provided directory '$1' for maven artifacts." 238 | maven_wd="$1" 239 | else 240 | common::info "Created temporary directory for maven artifacts." 241 | maven_wd=$(mktemp -d) 242 | fi 243 | 244 | common::_prepare_artifact_for_sonatype 245 | 246 | local pom_file="${maven_wd}/pom-${MAVEN_ARTIFACT}.xml" 247 | 248 | if [[ "${deploy_to_sonatype}" == true ]]; then 249 | common::info "Deploying artifacts to sonatype..." 250 | # Use maven to sign and deploy jar, sources jar and javadocs jar to OSS sonatype 251 | mvn -f "${pom_file}" clean deploy "-DautoPublish=${sonatype_auto_publish}" 252 | 253 | common::info "Deployment completed." 254 | else 255 | common::info "Packaging and installing maven artifacts locally..." 256 | mvn -f "${pom_file}" clean install 257 | 258 | common::info "Maven artifacts created in ${maven_wd}" 259 | common::info "Deployment not requested. No artifacts will be deployed." 260 | # set maven_wd to empty string so it's not deleted in cleanup_temp_files 261 | maven_wd="" 262 | fi 263 | 264 | common::cleanup_temp_files 265 | } 266 | 267 | common::cleanup_temp_files() { 268 | if [[ -d "${maven_wd:-}" ]]; then 269 | rm -rf "${maven_wd}" 270 | fi 271 | } 272 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright 2017 Google Inc. 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. --------------------------------------------------------------------------------