Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright (C) 2016 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.api.tools.framework.model;
import com.google.api.tools.framework.model.ExtensionPool.Extension;
import com.google.common.base.Joiner;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.Maps;
import com.google.protobuf.DescriptorProtos;
import com.google.protobuf.DescriptorProtos.FileDescriptorProto;
import com.google.protobuf.DescriptorProtos.ServiceDescriptorProto;
import com.google.protobuf.Syntax;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
/**
* Represents a protocol buffer file.
*/
public class ProtoFile extends ProtoContainerElement {
private static final Joiner DOT_JOINER = Joiner.on('.');
// Locations for documentation in proto files.
private static final ImmutableList FILE_DOC_LOCATIONS = ImmutableList.of(
"12", // syntax statement
"8", // option statement
"2" // package statement
);
/**
* Creates a new protocol file backed up by the given descriptor.
*/
public static ProtoFile create(Model model, FileDescriptorProto proto, boolean isSource,
ExtensionPool extensionPool) {
return new ProtoFile(model, proto, isSource, extensionPool);
}
// The location path is empty for ProtoFile element.
private static final String PATH = "";
private final Model model;
private final FileDescriptorProto proto;
private final boolean isSource;
private final ImmutableList interfaces;
private final ImmutableListMultimap locationMap;
private final Map protoToLocation = Maps.newHashMap();
private final Map extensions = Maps.newHashMap();
private final Syntax syntax;
private ProtoFile(Model model, FileDescriptorProto proto, boolean isSource,
ExtensionPool extensionPool) {
super(null, proto.getName(), PATH);
this.model = model;
this.isSource = isSource;
this.proto = proto;
buildChildren(proto.getMessageTypeList(),
proto.getEnumTypeList(),
PATH,
FileDescriptorProto.MESSAGE_TYPE_FIELD_NUMBER,
FileDescriptorProto.ENUM_TYPE_FIELD_NUMBER,
extensionPool);
// Build services.
ImmutableList.Builder interfacesBuilder = ImmutableList.builder();
List serviceProtos = proto.getServiceList();
for (int i = 0; i < serviceProtos.size(); i++) {
String childPath = buildPath(null, FileDescriptorProto.SERVICE_FIELD_NUMBER, i);
interfacesBuilder.add(Interface.create(this, serviceProtos.get(i), childPath));
}
interfaces = interfacesBuilder.build();
// Build location map
ImmutableListMultimap.Builder builder =
ImmutableListMultimap.builder();
for (DescriptorProtos.SourceCodeInfo.Location location :
proto.getSourceCodeInfo().getLocationList()) {
builder.put(DOT_JOINER.join(location.getPathList()), location);
}
// Add all extension locations
for (Entry entry : extensions.entrySet()) {
builder.put(entry.getKey().getPath(), entry.getKey().getLocation());
protoToLocation.put(entry.getValue(), entry.getKey().getFileLocation());
}
locationMap = builder.build();
// Initialize ProtoFile location.
protoToLocation.put(this, new SimpleLocation(proto.getName()));
syntax = getProtoSyntax(proto);
}
@Override public String toString() {
return "file " + getSimpleName();
}
/**
* Returns true if this object represents something that is configured as deprecated.
*/
@Override public boolean isDeprecated() {
return proto.getOptions().getDeprecated();
}
/**
* Returns true if this file is a proper source, in contrast to a dependency.
*/
public boolean isSource() {
return isSource;
}
@Override
public Model getModel() {
return model;
}
@Override
public String getFullName() {
return proto.getPackage();
}
@Override
public ProtoFile getFile() {
return this;
}
@Override
public Location getLocation() {
return protoToLocation.get(this);
}
/**
* Returns the file descriptor proto.
*/
public FileDescriptorProto getProto() {
return proto;
}
/**
* Returns the dependencies.
*/
public ImmutableList getDependencies() {
ImmutableList.Builder builder = ImmutableList.builder();
for (ProtoFile file : model.getFiles()) {
if (proto.getDependencyList().contains(file.getSimpleName())) {
builder.add(file);
}
}
return builder.build();
}
/**
* Returns the interfaces in this file.
*/
public ImmutableList getInterfaces() {
return interfaces;
}
/**
* Returns the interfaces reachable with active scoper.
*/
public Iterable getReachableInterfaces() {
return getModel().reachable(interfaces);
}
/**
* Package private helper to get the location backed up by this proto file for the given element.
*/
Location getLocation(ProtoElement element) {
if (protoToLocation.containsKey(element)) {
return protoToLocation.get(element);
}
Location location =
SimpleLocation.convertFrom(getSourceCodeLocation(element.getPath()), element);
protoToLocation.put(element, location);
return location;
}
/**
* Helper to get the documentation backed up by this proto file for the given
* element.
*/
public String getDocumentation(ProtoElement element) {
if (element instanceof ProtoFile) {
// For files themselves, comments from multiple locations are composed.
StringBuilder result = new StringBuilder();
for (String path : FILE_DOC_LOCATIONS) {
String comment = getDocumentation(path);
if (Strings.isNullOrEmpty(comment)) {
continue;
}
if (result.length() > 0) {
result.append('\n');
}
result.append(comment);
}
return result.toString();
} else {
return getDocumentation(element.getPath());
}
}
@Override
public Syntax getSyntax() {
return syntax;
}
private String getDocumentation(String path) {
String comment = "";
DescriptorProtos.SourceCodeInfo.Location location = getSourceCodeLocation(path);
if (location != null) {
if (!Strings.isNullOrEmpty(location.getLeadingComments())) {
comment = location.getLeadingComments();
}
if (!Strings.isNullOrEmpty(location.getTrailingComments())){
comment += location.getTrailingComments();
}
}
return comment;
}
private DescriptorProtos.SourceCodeInfo.Location getSourceCodeLocation(String path) {
if (locationMap.containsKey(path)) {
// We get the first location.
return locationMap.get(path).get(0);
} else {
return null;
}
}
private static Syntax getProtoSyntax(FileDescriptorProto proto) {
if (!proto.hasSyntax()) {
// TODO(user): This can be removed once protoc outputs proto2 when proto2 is being used.
// According to liujisi@ it would break a lot of tests, so it is currently not done.
return Syntax.SYNTAX_PROTO2;
}
switch (proto.getSyntax()) {
case "proto2":
return Syntax.SYNTAX_PROTO2;
case "proto3":
return Syntax.SYNTAX_PROTO3;
default:
throw new IllegalArgumentException(
"Illegal proto syntax for file " + proto.getName() + ": " + proto.getSyntax());
}
}
void addExtension(Extension extension, Field field) {
extensions.put(extension, field);
}
}