Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(390)

Unified Diff: server/static/rpcexplorer/rpc-descriptor-util.html

Issue 1695893004: RPC Explorer (Closed) Base URL: https://chromium.googlesource.com/external/github.com/luci/luci-go@rpcepxlorer-deps
Patch Set: 80 chars Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « server/static/rpcexplorer/rpc-completer.html ('k') | server/static/rpcexplorer/rpc-editor.html » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: server/static/rpcexplorer/rpc-descriptor-util.html
diff --git a/server/static/rpcexplorer/rpc-descriptor-util.html b/server/static/rpcexplorer/rpc-descriptor-util.html
new file mode 100644
index 0000000000000000000000000000000000000000..7fca7b25c78f3d790e24d8f212d72c9ee2116661
--- /dev/null
+++ b/server/static/rpcexplorer/rpc-descriptor-util.html
@@ -0,0 +1,205 @@
+<!--
+ Copyright 2016 The Chromium Authors. All rights reserved.
+ Use of this source code is governed by a BSD-style license that can be
+ found in the LICENSE file.
+ -->
+
+<!--
+ rpcExplorer.descUtil exposes helper methods to work with protobuf
+ descriptor messages.
+ Primarily it implements name and comments resolution in a FileDescriptorSet.
+-->
+<script>
+ 'use strict';
+
+ var rpcExplorer = (function(rpcExplorer) {
+
+ rpcExplorer.descUtil = {
+
+ /**
+ * for all descriptors in the file annotate resolves
+ * SourceLocationInfo.Location message and assigns it to the
+ * source_code_info property of the descriptor.
+ * Prerequisite reading:
+ * https://github.com/luci/luci-go/blob/ea240d0/common/proto/google/descriptor/descriptor.proto#L713
+ * @param {FileDescriptorProto} file
+ */
+ annotate: function(file) {
+ if (!file.source_code_info) {
+ return;
+ }
+
+ // First, build a map { path -> location message }.
+ function key(path) {
+ var key = '';
+ for (var i = 0; i < path.length; i++) {
+ key += path[i] + '.';
+ }
+ return key;
+ }
+ var locationMap = {};
+ for (var i = 0; i < file.source_code_info.location.length; i++) {
+ var loc = file.source_code_info.location[i];
+ if (loc.path) {
+ locationMap[key(loc.path)] = loc;
+ }
+ }
+
+ // Now join all descriptors in file with the map.
+ var path = [];
+
+ function annotateList(list, field, fn) {
+ if (!list) {
+ return;
+ }
+ path.push(field, 0);
+ for (var i = 0; i < list.length; i++) {
+ path[path.length - 1] = i;
+ list[i].source_code_info = locationMap[key(path)];
+ if (fn) {
+ fn(list[i]);
+ }
+ }
+ path.pop();
+ path.pop();
+ }
+
+ // The magic numbers below are message field numbers defined in
+ // descriptor.proto.
+
+ function annotateMessage(msg) {
+ annotateList(msg.field, 2);
+ annotateList(msg.nested_type, 3, annotateMessage);
+ annotateList(msg.enum_type, 4, annotateEnum);
+ }
+
+ function annotateEnum(e) {
+ annotateList(e.value, 2);
+ }
+
+ function annotateService(svc) {
+ annotateList(svc.method, 2);
+ }
+
+ annotateList(file.message_type, 4, annotateMessage);
+ annotateList(file.enum_type, 5, annotateEnum);
+ annotateList(file.service, 6, annotateService);
+ },
+
+ /**
+ * Annotates a FileDescriptorSet.
+ */
+ annotateSet: function(fileSet) {
+ for (var i = 0; i < fileSet.file.length; i++) {
+ this.annotate(fileSet.file[i]);
+ }
+ },
+
+ splitFullName: function(fullName) {
+ var lastDot = fullName.lastIndexOf('.');
+ if (lastDot === -1) {
+ return {
+ pkg: '',
+ name: fullName
+ };
+ }
+
+ return {
+ pkg: fullName.substr(0, lastDot),
+ name: fullName.substr(lastDot + 1)
+ };
+ },
+
+ /**
+ * Resolves services, methods, messages, fields, enums and enum values.
+ */
+ resolve: function(desc, name) {
+ if (!desc || !name) {
+ return null;
+ }
+ name = this.splitFullName(name);
+
+ var self = this;
+
+ // searches in each list.
+ function checkLists(lists) {
+ if (!lists) {
+ return null;
+ }
+ for (var type in lists) {
+ var desc = self.findByName(lists[type], name.name);
+ if (desc) {
+ return {type: type, desc: desc };
+ }
+ }
+ return null;
+ }
+
+ // Check top-level descriptors.
+ for (var i = 0; i < desc.file.length; i++) {
+ var file = desc.file[i];
+ if (file['package'] != name.pkg) {
+ continue
+ }
+
+ var result = checkLists({
+ service: file.service,
+ messageType: file.message_type,
+ enumType: file.enum_type
+ });
+ if (result) {
+ return result;
+ }
+ }
+
+ // Possibly the entity we are resolving is not top-level and
+ // name.name references an object inside an object referenced by
+ // name.pkg. Try to resolve name.pkg.
+ var parent = this.resolve(desc, name.pkg);
+ if (!parent) {
+ return null;
+ }
+ switch (parent.type) {
+ case 'service':
+ return checkLists({ method: parent.desc.method });
+
+ case 'messageType':
+ return checkLists({
+ field: parent.desc.field,
+ messageType: parent.desc.nested_type,
+ enumType: parent.desc.enum_type
+ });
+
+ case 'enumType':
+ return checkLists({
+ enumValue: parent.desc.value,
+ });
+
+ default:
+ return null;
+ }
+ },
+
+ findByName: function(array, name) {
+ if (!array) {
+ return null;
+ }
+ for (var i = 0; i < array.length; i++) {
+ if (array[i].name === name) {
+ return array[i];
+ }
+ }
+ return null;
+ },
+
+ trimPrefixDot: function(name) {
+ if (typeof name === 'string' && name.charAt(0) === '.') {
+ name = name.substr(1);
+ }
+ return name;
+ }
+ };
+
+ return rpcExplorer;
+ }(rpcExplorer || {}));
+</script>
« no previous file with comments | « server/static/rpcexplorer/rpc-completer.html ('k') | server/static/rpcexplorer/rpc-editor.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698