Merge branch 'stable-3.5' into stable-3.6

* stable-3.5:
  gr-access-section: Fix exception when unknown name is set
  InMemoryModule: Add support for index lib module
  Expose proto package in plugin API

Release-Notes: skip
Change-Id: I8933f62998a97367f75b332dacaa3052f3c8c765
diff --git a/java/com/google/gerrit/testing/InMemoryModule.java b/java/com/google/gerrit/testing/InMemoryModule.java
index b9daa13..86ceb60 100644
--- a/java/com/google/gerrit/testing/InMemoryModule.java
+++ b/java/com/google/gerrit/testing/InMemoryModule.java
@@ -37,6 +37,7 @@
 import com.google.gerrit.server.FanOutExecutor;
 import com.google.gerrit.server.GerritPersonIdent;
 import com.google.gerrit.server.GerritPersonIdentProvider;
+import com.google.gerrit.server.LibModuleType;
 import com.google.gerrit.server.PluginUser;
 import com.google.gerrit.server.api.GerritApiModule;
 import com.google.gerrit.server.api.PluginApiModule;
@@ -243,13 +244,19 @@
     bind(AllChangesIndexer.class).toProvider(Providers.of(null));
     bind(AllGroupsIndexer.class).toProvider(Providers.of(null));
 
-    String indexTypeCfg = cfg.getString("index", null, "type");
-    IndexType indexType = new IndexType(indexTypeCfg != null ? indexTypeCfg : "fake");
-    // For custom index types, callers must provide their own module.
-    if (indexType.isLucene()) {
-      install(luceneIndexModule());
-    } else if (indexType.isFake()) {
-      install(fakeIndexModule());
+    // Index lib module has a higher priority than index type configuration.
+    String indexModule =
+        cfg.getString("index", null, "install" + LibModuleType.INDEX_MODULE_TYPE.getConfigKey());
+    if (indexModule != null) {
+      install(indexModule(indexModule));
+    } else {
+      String indexTypeCfg = cfg.getString("index", null, "type");
+      IndexType indexType = new IndexType(indexTypeCfg != null ? indexTypeCfg : "fake");
+      if (indexType.isLucene()) {
+        install(luceneIndexModule());
+      } else if (indexType.isFake()) {
+        install(fakeIndexModule());
+      }
     }
     bind(ServerInformationImpl.class);
     bind(ServerInformation.class).to(ServerInformationImpl.class);
diff --git a/plugins/BUILD b/plugins/BUILD
index 7862b1c..32efa3e 100644
--- a/plugins/BUILD
+++ b/plugins/BUILD
@@ -64,6 +64,7 @@
     "//java/com/google/gerrit/server/logging",
     "//java/com/google/gerrit/server/schema",
     "//java/com/google/gerrit/server/util/time",
+    "//java/com/google/gerrit/proto",
     "//java/com/google/gerrit/util/cli",
     "//java/com/google/gerrit/util/http",
     "//java/com/google/gerrit/util/logging",
diff --git a/polygerrit-ui/app/elements/admin/gr-access-section/gr-access-section.ts b/polygerrit-ui/app/elements/admin/gr-access-section/gr-access-section.ts
index 8fa2e90..2c83ed3 100644
--- a/polygerrit-ui/app/elements/admin/gr-access-section/gr-access-section.ts
+++ b/polygerrit-ui/app/elements/admin/gr-access-section/gr-access-section.ts
@@ -403,9 +403,9 @@
     permission: PermissionArrayItem<EditablePermissionInfo>
   ): string | undefined {
     if (this.section?.id === GLOBAL_NAME) {
-      return this.capabilities?.[permission.id].name;
+      return this.capabilities?.[permission.id]?.name;
     } else if (AccessPermissions[permission.id]) {
-      return AccessPermissions[permission.id].name;
+      return AccessPermissions[permission.id]?.name;
     } else if (permission.value.label) {
       let behalfOf = '';
       if (permission.id.startsWith('labelAs-')) {
diff --git a/polygerrit-ui/app/elements/admin/gr-access-section/gr-access-section_test.ts b/polygerrit-ui/app/elements/admin/gr-access-section/gr-access-section_test.ts
index f4d81c4..1c4c437 100644
--- a/polygerrit-ui/app/elements/admin/gr-access-section/gr-access-section_test.ts
+++ b/polygerrit-ui/app/elements/admin/gr-access-section/gr-access-section_test.ts
@@ -224,6 +224,12 @@
         element.capabilities![permission.id].name
       );
 
+      permission = {
+        id: 'non-existent' as GitRef,
+        value: {rules: {}},
+      };
+      assert.isUndefined(element.computePermissionName(permission));
+
       element.section.id = 'refs/for/*' as GitRef;
       permission = {
         id: 'abandon' as GitRef,