189eaab56f3ff913c247397b858fac3c8d3d4a206Christopher Wiley/*
289eaab56f3ff913c247397b858fac3c8d3d4a206Christopher Wiley * Copyright (C) 2015, The Android Open Source Project
389eaab56f3ff913c247397b858fac3c8d3d4a206Christopher Wiley *
489eaab56f3ff913c247397b858fac3c8d3d4a206Christopher Wiley * Licensed under the Apache License, Version 2.0 (the "License");
589eaab56f3ff913c247397b858fac3c8d3d4a206Christopher Wiley * you may not use this file except in compliance with the License.
689eaab56f3ff913c247397b858fac3c8d3d4a206Christopher Wiley * You may obtain a copy of the License at
789eaab56f3ff913c247397b858fac3c8d3d4a206Christopher Wiley *
889eaab56f3ff913c247397b858fac3c8d3d4a206Christopher Wiley *     http://www.apache.org/licenses/LICENSE-2.0
989eaab56f3ff913c247397b858fac3c8d3d4a206Christopher Wiley *
1089eaab56f3ff913c247397b858fac3c8d3d4a206Christopher Wiley * Unless required by applicable law or agreed to in writing, software
1189eaab56f3ff913c247397b858fac3c8d3d4a206Christopher Wiley * distributed under the License is distributed on an "AS IS" BASIS,
1289eaab56f3ff913c247397b858fac3c8d3d4a206Christopher Wiley * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1389eaab56f3ff913c247397b858fac3c8d3d4a206Christopher Wiley * See the License for the specific language governing permissions and
1489eaab56f3ff913c247397b858fac3c8d3d4a206Christopher Wiley * limitations under the License.
1589eaab56f3ff913c247397b858fac3c8d3d4a206Christopher Wiley */
16ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski
17f690be5044a56fdf75bb0bcae640074ec97023cdChristopher Wiley#include "aidl.h"
18ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski
19f690be5044a56fdf75bb0bcae640074ec97023cdChristopher Wiley#include <fcntl.h>
20c16e5e70c0d570839f41c49a900035c5c82ecd95Christopher Wiley#include <iostream>
21f690be5044a56fdf75bb0bcae640074ec97023cdChristopher Wiley#include <map>
22ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski#include <stdio.h>
23ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski#include <stdlib.h>
24ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski#include <string.h>
25f690be5044a56fdf75bb0bcae640074ec97023cdChristopher Wiley#include <sys/param.h>
26f690be5044a56fdf75bb0bcae640074ec97023cdChristopher Wiley#include <sys/stat.h>
27f690be5044a56fdf75bb0bcae640074ec97023cdChristopher Wiley#include <unistd.h>
28ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski
29549b6e27c013ec44272be15b3da47da39721864dElliott Hughes#ifdef _WIN32
30ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski#include <io.h>
3115ce994e02e841be0a2dca3005884fa5d7f81b58Andrew Hsieh#include <direct.h>
32ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski#include <sys/stat.h>
33ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski#endif
34ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski
350a62067f35e957493bc37c4b42dfdcfc16353831Elliott Hughes#include <android-base/strings.h>
36f690be5044a56fdf75bb0bcae640074ec97023cdChristopher Wiley
37f690be5044a56fdf75bb0bcae640074ec97023cdChristopher Wiley#include "aidl_language.h"
38eb1acc1cf7dbf578d8ab2e596982c4c635aa9865Christopher Wiley#include "generate_cpp.h"
39f690be5044a56fdf75bb0bcae640074ec97023cdChristopher Wiley#include "generate_java.h"
4072877acd3b57462fcd452bff4a9d7ff936936a8eChristopher Wiley#include "import_resolver.h"
41f690be5044a56fdf75bb0bcae640074ec97023cdChristopher Wiley#include "logging.h"
42f690be5044a56fdf75bb0bcae640074ec97023cdChristopher Wiley#include "options.h"
43f690be5044a56fdf75bb0bcae640074ec97023cdChristopher Wiley#include "os.h"
44e3550c6679939d2bf5f35c540cd83198ab156fb7Christopher Wiley#include "type_cpp.h"
45775fa1f7db4626b85e5185149b054821fc605c2bChristopher Wiley#include "type_java.h"
4684c1eacc7f09377d7724f0783187b0477fe7c2baChristopher Wiley#include "type_namespace.h"
47f690be5044a56fdf75bb0bcae640074ec97023cdChristopher Wiley
48ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski#ifndef O_BINARY
49ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski#  define O_BINARY  0
50ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski#endif
51ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski
523a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wileyusing android::base::Join;
53d76067c52b6bc0587aa26ecae34a49e6cbdae404Christopher Wileyusing android::base::Split;
54c16e5e70c0d570839f41c49a900035c5c82ecd95Christopher Wileyusing std::cerr;
55c16e5e70c0d570839f41c49a900035c5c82ecd95Christopher Wileyusing std::endl;
569f4c7ae970a27bcf081d838671b4f4d7505861b3Christopher Wileyusing std::map;
579f4c7ae970a27bcf081d838671b4f4d7505861b3Christopher Wileyusing std::set;
589f4c7ae970a27bcf081d838671b4f4d7505861b3Christopher Wileyusing std::string;
5984c1eacc7f09377d7724f0783187b0477fe7c2baChristopher Wileyusing std::unique_ptr;
609f4c7ae970a27bcf081d838671b4f4d7505861b3Christopher Wileyusing std::vector;
61ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski
62f690be5044a56fdf75bb0bcae640074ec97023cdChristopher Wileynamespace android {
63f690be5044a56fdf75bb0bcae640074ec97023cdChristopher Wileynamespace aidl {
64f690be5044a56fdf75bb0bcae640074ec97023cdChristopher Wileynamespace {
65ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski
66f690be5044a56fdf75bb0bcae640074ec97023cdChristopher Wiley// The following are gotten as the offset from the allowable id's between
67f690be5044a56fdf75bb0bcae640074ec97023cdChristopher Wiley// android.os.IBinder.FIRST_CALL_TRANSACTION=1 and
68f690be5044a56fdf75bb0bcae640074ec97023cdChristopher Wiley// android.os.IBinder.LAST_CALL_TRANSACTION=16777215
69f690be5044a56fdf75bb0bcae640074ec97023cdChristopher Wileyconst int kMinUserSetMethodId = 0;
70f690be5044a56fdf75bb0bcae640074ec97023cdChristopher Wileyconst int kMaxUserSetMethodId = 16777214;
71ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski
7242727f851672ff8f3099db81fa21c969e553e150Casey Dahlinbool check_filename(const std::string& filename,
7342727f851672ff8f3099db81fa21c969e553e150Casey Dahlin                    const std::string& package,
7442727f851672ff8f3099db81fa21c969e553e150Casey Dahlin                    const std::string& name,
7542727f851672ff8f3099db81fa21c969e553e150Casey Dahlin                    unsigned line) {
76ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski    const char* p;
77ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski    string expected;
78ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski    string fn;
79ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski    size_t len;
80ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski    bool valid = false;
81ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski
828decf95ffeffcc8aa14aa743ae398bc38d54b0acChristopher Wiley    if (!IoDelegate::GetAbsolutePath(filename, &fn)) {
838decf95ffeffcc8aa14aa743ae398bc38d54b0acChristopher Wiley      return false;
84ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski    }
85ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski
86fb7da2e62fe66b0a57ffbb0304f5884024a68f1cCasey Dahlin    if (!package.empty()) {
87ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski        expected = package;
88ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski        expected += '.';
89ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski    }
90ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski
91ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski    len = expected.length();
92ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski    for (size_t i=0; i<len; i++) {
93ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski        if (expected[i] == '.') {
94ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski            expected[i] = OS_PATH_SEPARATOR;
95ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski        }
96ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski    }
97ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski
98fb7da2e62fe66b0a57ffbb0304f5884024a68f1cCasey Dahlin    expected.append(name, 0, name.find('.'));
998f8cc9b91a8d0b4942a978e9d2edc5337503d583Christopher Wiley
100ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski    expected += ".aidl";
101ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski
102ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski    len = fn.length();
103ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski    valid = (len >= expected.length());
104ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski
105ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski    if (valid) {
106ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski        p = fn.c_str() + (len - expected.length());
107ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski
108ce310dab0a33eff529e50a9de9ef59435b307e76Elliott Hughes#ifdef _WIN32
109ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski        if (OS_PATH_SEPARATOR != '/') {
110ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski            // Input filename under cygwin most likely has / separators
111ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski            // whereas the expected string uses \\ separators. Adjust
112ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski            // them accordingly.
113ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski          for (char *c = const_cast<char *>(p); *c; ++c) {
114ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski                if (*c == '/') *c = OS_PATH_SEPARATOR;
115ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski            }
116ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski        }
117ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski#endif
118ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski
119482eefbaf0c1b02ae45d8020fa839fce630ecee7Yabin Cui        // aidl assumes case-insensitivity on Mac Os and Windows.
120482eefbaf0c1b02ae45d8020fa839fce630ecee7Yabin Cui#if defined(__linux__)
121ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski        valid = (expected == p);
122ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski#else
123ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski        valid = !strcasecmp(expected.c_str(), p);
124ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski#endif
125ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski    }
126ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski
127ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski    if (!valid) {
128ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski        fprintf(stderr, "%s:%d interface %s should be declared in a file"
129ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski                " called %s.\n",
130fb7da2e62fe66b0a57ffbb0304f5884024a68f1cCasey Dahlin                filename.c_str(), line, name.c_str(), expected.c_str());
131ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski    }
132ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski
13342727f851672ff8f3099db81fa21c969e553e150Casey Dahlin    return valid;
134ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski}
135ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski
136c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlinbool check_filenames(const std::string& filename, const AidlDocument* doc) {
137c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlin  if (!doc)
13842727f851672ff8f3099db81fa21c969e553e150Casey Dahlin    return true;
13942727f851672ff8f3099db81fa21c969e553e150Casey Dahlin
140c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlin  const AidlInterface* interface = doc->GetInterface();
141c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlin
142c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlin  if (interface) {
143c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlin    return check_filename(filename, interface->GetPackage(),
144c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlin                          interface->GetName(), interface->GetLine());
14542727f851672ff8f3099db81fa21c969e553e150Casey Dahlin  }
14642727f851672ff8f3099db81fa21c969e553e150Casey Dahlin
14742727f851672ff8f3099db81fa21c969e553e150Casey Dahlin  bool success = true;
14842727f851672ff8f3099db81fa21c969e553e150Casey Dahlin
149c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlin  for (const auto& item : doc->GetParcelables()) {
150c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlin    success &= check_filename(filename, item->GetPackage(), item->GetName(),
151c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlin                              item->GetLine());
152c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlin  }
15342727f851672ff8f3099db81fa21c969e553e150Casey Dahlin
15442727f851672ff8f3099db81fa21c969e553e150Casey Dahlin  return success;
155ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski}
156ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski
1570edf34239909bbc16e884ea2517e5f3398185d0fCasey Dahlinbool gather_types(const std::string& filename,
158c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlin                  const AidlDocument* doc,
15984c1eacc7f09377d7724f0783187b0477fe7c2baChristopher Wiley                  TypeNamespace* types) {
16084c1eacc7f09377d7724f0783187b0477fe7c2baChristopher Wiley  bool success = true;
16184c1eacc7f09377d7724f0783187b0477fe7c2baChristopher Wiley
162c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlin  const AidlInterface* interface = doc->GetInterface();
16342727f851672ff8f3099db81fa21c969e553e150Casey Dahlin
164c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlin  if (interface)
165c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlin    return types->AddBinderType(*interface, filename);
16642727f851672ff8f3099db81fa21c969e553e150Casey Dahlin
167c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlin  for (const auto& item : doc->GetParcelables()) {
168c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlin    success &= types->AddParcelableType(*item, filename);
16984c1eacc7f09377d7724f0783187b0477fe7c2baChristopher Wiley  }
17042727f851672ff8f3099db81fa21c969e553e150Casey Dahlin
17184c1eacc7f09377d7724f0783187b0477fe7c2baChristopher Wiley  return success;
172ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski}
173ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski
174fb4b22dfbe0f87aaad492dc8a25201179c235baeChristopher Wileyint check_types(const string& filename,
17598a544b567e20f6c8492e1d4eb8869e759ae74d9Casey Dahlin                const AidlInterface* c,
176fb4b22dfbe0f87aaad492dc8a25201179c235baeChristopher Wiley                TypeNamespace* types) {
177fb4b22dfbe0f87aaad492dc8a25201179c235baeChristopher Wiley  int err = 0;
178f4a9311fa018c78a7b30a73bd8ebbaa33c701ae4Casey Dahlin
179f4a9311fa018c78a7b30a73bd8ebbaa33c701ae4Casey Dahlin  // Has to be a pointer due to deleting copy constructor. No idea why.
180f4a9311fa018c78a7b30a73bd8ebbaa33c701ae4Casey Dahlin  map<string, const AidlMethod*> method_names;
181fb7da2e62fe66b0a57ffbb0304f5884024a68f1cCasey Dahlin  for (const auto& m : c->GetMethods()) {
1820c6fcecd6b74cf5f02c6fa0793be51e2f7fbf191Casey Dahlin    bool oneway = m->IsOneway() || c->IsOneway();
1830c6fcecd6b74cf5f02c6fa0793be51e2f7fbf191Casey Dahlin
184934a82d1b045a5944d115dece4cf01f539103c11Christopher Wiley    if (!types->MaybeAddContainerType(m->GetType())) {
185fb4b22dfbe0f87aaad492dc8a25201179c235baeChristopher Wiley      err = 1;  // return type is invalid
186ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski    }
187ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski
188a2f77c40fb6287895e2030055c0104eac0a1f73aCasey Dahlin    const ValidatableType* return_type =
18957dbe24bcb8f4509a876e8445c78d9504d7e616aCasey Dahlin        types->GetReturnType(m->GetType(), filename);
190a2f77c40fb6287895e2030055c0104eac0a1f73aCasey Dahlin
19157dbe24bcb8f4509a876e8445c78d9504d7e616aCasey Dahlin    if (!return_type) {
19257dbe24bcb8f4509a876e8445c78d9504d7e616aCasey Dahlin      err = 1;
193a2f77c40fb6287895e2030055c0104eac0a1f73aCasey Dahlin    }
194a2f77c40fb6287895e2030055c0104eac0a1f73aCasey Dahlin
195a2f77c40fb6287895e2030055c0104eac0a1f73aCasey Dahlin    m->GetMutableType()->SetLanguageType(return_type);
196a2f77c40fb6287895e2030055c0104eac0a1f73aCasey Dahlin
1970c6fcecd6b74cf5f02c6fa0793be51e2f7fbf191Casey Dahlin    if (oneway && m->GetType().GetName() != "void") {
1980c6fcecd6b74cf5f02c6fa0793be51e2f7fbf191Casey Dahlin        cerr << filename << ":" << m->GetLine()
19945db9eec8a0bb71ba1afb5b8c9da72fd0f60028fChristopher Wiley            << " oneway method '" << m->GetName() << "' cannot return a value"
20045db9eec8a0bb71ba1afb5b8c9da72fd0f60028fChristopher Wiley            << endl;
2010c6fcecd6b74cf5f02c6fa0793be51e2f7fbf191Casey Dahlin        err = 1;
2020c6fcecd6b74cf5f02c6fa0793be51e2f7fbf191Casey Dahlin    }
2030c6fcecd6b74cf5f02c6fa0793be51e2f7fbf191Casey Dahlin
204ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski    int index = 1;
205f4a9311fa018c78a7b30a73bd8ebbaa33c701ae4Casey Dahlin    for (const auto& arg : m->GetArguments()) {
206934a82d1b045a5944d115dece4cf01f539103c11Christopher Wiley      if (!types->MaybeAddContainerType(arg->GetType())) {
207fb4b22dfbe0f87aaad492dc8a25201179c235baeChristopher Wiley        err = 1;
208fb4b22dfbe0f87aaad492dc8a25201179c235baeChristopher Wiley      }
2090c6fcecd6b74cf5f02c6fa0793be51e2f7fbf191Casey Dahlin
210a2f77c40fb6287895e2030055c0104eac0a1f73aCasey Dahlin      const ValidatableType* arg_type =
21157dbe24bcb8f4509a876e8445c78d9504d7e616aCasey Dahlin          types->GetArgType(*arg, index, filename);
212a2f77c40fb6287895e2030055c0104eac0a1f73aCasey Dahlin
21357dbe24bcb8f4509a876e8445c78d9504d7e616aCasey Dahlin      if (!arg_type) {
21457dbe24bcb8f4509a876e8445c78d9504d7e616aCasey Dahlin        err = 1;
215a2f77c40fb6287895e2030055c0104eac0a1f73aCasey Dahlin      }
216a2f77c40fb6287895e2030055c0104eac0a1f73aCasey Dahlin
217a2f77c40fb6287895e2030055c0104eac0a1f73aCasey Dahlin      arg->GetMutableType()->SetLanguageType(arg_type);
218a2f77c40fb6287895e2030055c0104eac0a1f73aCasey Dahlin
2190c6fcecd6b74cf5f02c6fa0793be51e2f7fbf191Casey Dahlin      if (oneway && arg->IsOut()) {
2200c6fcecd6b74cf5f02c6fa0793be51e2f7fbf191Casey Dahlin        cerr << filename << ":" << m->GetLine()
22145db9eec8a0bb71ba1afb5b8c9da72fd0f60028fChristopher Wiley            << " oneway method '" << m->GetName()
22245db9eec8a0bb71ba1afb5b8c9da72fd0f60028fChristopher Wiley            << "' cannot have out parameters" << endl;
2230c6fcecd6b74cf5f02c6fa0793be51e2f7fbf191Casey Dahlin        err = 1;
2240c6fcecd6b74cf5f02c6fa0793be51e2f7fbf191Casey Dahlin      }
225ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski    }
226ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski
227f4a9311fa018c78a7b30a73bd8ebbaa33c701ae4Casey Dahlin    auto it = method_names.find(m->GetName());
228fb4b22dfbe0f87aaad492dc8a25201179c235baeChristopher Wiley    // prevent duplicate methods
229f4a9311fa018c78a7b30a73bd8ebbaa33c701ae4Casey Dahlin    if (it == method_names.end()) {
230f4a9311fa018c78a7b30a73bd8ebbaa33c701ae4Casey Dahlin      method_names[m->GetName()] = m.get();
231fb4b22dfbe0f87aaad492dc8a25201179c235baeChristopher Wiley    } else {
232f4a9311fa018c78a7b30a73bd8ebbaa33c701ae4Casey Dahlin      cerr << filename << ":" << m->GetLine()
233f4a9311fa018c78a7b30a73bd8ebbaa33c701ae4Casey Dahlin           << " attempt to redefine method " << m->GetName() << "," << endl
234f4a9311fa018c78a7b30a73bd8ebbaa33c701ae4Casey Dahlin           << filename << ":" << it->second->GetLine()
235fb4b22dfbe0f87aaad492dc8a25201179c235baeChristopher Wiley           << "    previously defined here." << endl;
236fb4b22dfbe0f87aaad492dc8a25201179c235baeChristopher Wiley      err = 1;
237ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski    }
238fb4b22dfbe0f87aaad492dc8a25201179c235baeChristopher Wiley  }
239fb4b22dfbe0f87aaad492dc8a25201179c235baeChristopher Wiley  return err;
240ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski}
241ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski
2423a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wileyvoid write_common_dep_file(const string& output_file,
2433a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley                           const vector<string>& aidl_sources,
2443a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley                           CodeWriter* writer) {
2453a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley  // Encode that the output file depends on aidl input files.
2463a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley  writer->Write("%s : \\\n", output_file.c_str());
2473a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley  writer->Write("  %s", Join(aidl_sources, " \\\n  ").c_str());
2483a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley  writer->Write("\n\n");
2493a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley
2503a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley  // Output "<input_aidl_file>: " so make won't fail if the input .aidl file
2513a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley  // has been deleted, moved or renamed in incremental build.
2523a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley  for (const auto& src : aidl_sources) {
2533a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley    writer->Write("%s :\n", src.c_str());
2543a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley  }
2553a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley}
2563a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley
2573a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wileybool write_java_dep_file(const JavaOptions& options,
2583a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley                         const vector<unique_ptr<AidlImport>>& imports,
2598f314b0d4c3f195c98c6dd7e671fc2b9d4bfa76fChristopher Wiley                         const IoDelegate& io_delegate,
2608f314b0d4c3f195c98c6dd7e671fc2b9d4bfa76fChristopher Wiley                         const string& output_file_name) {
2613a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley  string dep_file_name = options.DependencyFilePath();
2623a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley  if (dep_file_name.empty()) {
2633a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley    return true;  // nothing to do
2643a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley  }
265ef4132c27c313d9c84faf77a84a4ac97f69445b3Christopher Wiley  CodeWriterPtr writer = io_delegate.GetCodeWriter(dep_file_name);
266a30a45e7b7cdd3c4b5b7c5dcc6ce005abfe7c90fChristopher Wiley  if (!writer) {
2673a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley    LOG(ERROR) << "Could not open dependency file: " << dep_file_name;
2683a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley    return false;
269a30a45e7b7cdd3c4b5b7c5dcc6ce005abfe7c90fChristopher Wiley  }
2700edf34239909bbc16e884ea2517e5f3398185d0fCasey Dahlin
2713a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley  vector<string> source_aidl = {options.input_file_name_};
272a30a45e7b7cdd3c4b5b7c5dcc6ce005abfe7c90fChristopher Wiley  for (const auto& import : imports) {
2733a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley    if (!import->GetFilename().empty()) {
2743a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley      source_aidl.push_back(import->GetFilename());
275ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski    }
276a30a45e7b7cdd3c4b5b7c5dcc6ce005abfe7c90fChristopher Wiley  }
277ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski
2788f314b0d4c3f195c98c6dd7e671fc2b9d4bfa76fChristopher Wiley  write_common_dep_file(output_file_name, source_aidl, writer.get());
279ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski
2803a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley  return true;
2813a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley}
2820e4861a4a2abc9f41aab2d59944f2b6f52f3bfa2Ying Wang
2833a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wileybool write_cpp_dep_file(const CppOptions& options,
2843a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley                        const AidlInterface& interface,
2853a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley                        const vector<unique_ptr<AidlImport>>& imports,
2863a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley                        const IoDelegate& io_delegate) {
2873a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley  using ::android::aidl::cpp::HeaderFile;
2883a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley  using ::android::aidl::cpp::ClassNames;
2893a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley
2903a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley  string dep_file_name = options.DependencyFilePath();
2913a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley  if (dep_file_name.empty()) {
2923a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley    return true;  // nothing to do
2933a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley  }
2943a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley  CodeWriterPtr writer = io_delegate.GetCodeWriter(dep_file_name);
2953a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley  if (!writer) {
2963a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley    LOG(ERROR) << "Could not open dependency file: " << dep_file_name;
2973a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley    return false;
2983a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley  }
2993a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley
3003a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley  vector<string> source_aidl = {options.InputFileName()};
301a30a45e7b7cdd3c4b5b7c5dcc6ce005abfe7c90fChristopher Wiley  for (const auto& import : imports) {
3023a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley    if (!import->GetFilename().empty()) {
3033a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley      source_aidl.push_back(import->GetFilename());
304ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski    }
305a30a45e7b7cdd3c4b5b7c5dcc6ce005abfe7c90fChristopher Wiley  }
3063a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley
3073a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley  vector<string> headers;
3083a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley  for (ClassNames c : {ClassNames::CLIENT,
3093a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley                       ClassNames::SERVER,
3103a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley                       ClassNames::INTERFACE}) {
3113a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley    headers.push_back(options.OutputHeaderDir() + '/' +
3123a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley                      HeaderFile(interface, c, false /* use_os_sep */));
3133a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley  }
3143a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley
3153a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley  write_common_dep_file(options.OutputCppFilePath(), source_aidl, writer.get());
3163a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley  writer->Write("\n");
3173a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley
3183a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley  // Generated headers also depend on the source aidl files.
3193a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley  writer->Write("%s : \\\n    %s\n", Join(headers, " \\\n    ").c_str(),
3203a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley                Join(source_aidl, " \\\n    ").c_str());
3213a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley
3223a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley  return true;
323ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski}
324ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski
32590be4e3fe6d16ea8e8263b80989ef2ab4e6ef9c6Christopher Wileystring generate_outputFileName(const JavaOptions& options,
32690be4e3fe6d16ea8e8263b80989ef2ab4e6ef9c6Christopher Wiley                               const AidlInterface& interface) {
32790be4e3fe6d16ea8e8263b80989ef2ab4e6ef9c6Christopher Wiley    string name = interface.GetName();
32890be4e3fe6d16ea8e8263b80989ef2ab4e6ef9c6Christopher Wiley    string package = interface.GetPackage();
329ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski    string result;
330ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski
331ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski    // create the path to the destination folder based on the
332ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski    // interface package name
3338f8cc9b91a8d0b4942a978e9d2edc5337503d583Christopher Wiley    result = options.output_base_folder_;
334ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski    result += OS_PATH_SEPARATOR;
335ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski
336ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski    string packageStr = package;
337ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski    size_t len = packageStr.length();
338ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski    for (size_t i=0; i<len; i++) {
339ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski        if (packageStr[i] == '.') {
340ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski            packageStr[i] = OS_PATH_SEPARATOR;
341ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski        }
342ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski    }
343ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski
344ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski    result += packageStr;
345ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski
346ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski    // add the filename by replacing the .aidl extension to .java
347ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski    result += OS_PATH_SEPARATOR;
348fb7da2e62fe66b0a57ffbb0304f5884024a68f1cCasey Dahlin    result.append(name, 0, name.find('.'));
349ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski    result += ".java";
350ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski
351ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski    return result;
352ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski}
353ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski
354f690be5044a56fdf75bb0bcae640074ec97023cdChristopher Wileyint check_and_assign_method_ids(const char * filename,
3555c69deb2a90d487d7b57618eb07a34c85c8112e7Casey Dahlin                                const std::vector<std::unique_ptr<AidlMethod>>& items) {
356ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski    // Check whether there are any methods with manually assigned id's and any that are not.
357ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski    // Either all method id's must be manually assigned or all of them must not.
358ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski    // Also, check for duplicates of user set id's and that the id's are within the proper bounds.
359ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski    set<int> usedIds;
360ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski    bool hasUnassignedIds = false;
361ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski    bool hasAssignedIds = false;
3625c69deb2a90d487d7b57618eb07a34c85c8112e7Casey Dahlin    for (const auto& item : items) {
363f4a9311fa018c78a7b30a73bd8ebbaa33c701ae4Casey Dahlin        if (item->HasId()) {
364dff80e51334ba15850f21189f47665d2fc846b68Casey Dahlin            hasAssignedIds = true;
365dff80e51334ba15850f21189f47665d2fc846b68Casey Dahlin            // Ensure that the user set id is not duplicated.
366f4a9311fa018c78a7b30a73bd8ebbaa33c701ae4Casey Dahlin            if (usedIds.find(item->GetId()) != usedIds.end()) {
367dff80e51334ba15850f21189f47665d2fc846b68Casey Dahlin                // We found a duplicate id, so throw an error.
368ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski                fprintf(stderr,
369dff80e51334ba15850f21189f47665d2fc846b68Casey Dahlin                        "%s:%d Found duplicate method id (%d) for method: %s\n",
370f4a9311fa018c78a7b30a73bd8ebbaa33c701ae4Casey Dahlin                        filename, item->GetLine(),
371f4a9311fa018c78a7b30a73bd8ebbaa33c701ae4Casey Dahlin                        item->GetId(), item->GetName().c_str());
372dff80e51334ba15850f21189f47665d2fc846b68Casey Dahlin                return 1;
373dff80e51334ba15850f21189f47665d2fc846b68Casey Dahlin            }
374dff80e51334ba15850f21189f47665d2fc846b68Casey Dahlin            // Ensure that the user set id is within the appropriate limits
375f4a9311fa018c78a7b30a73bd8ebbaa33c701ae4Casey Dahlin            if (item->GetId() < kMinUserSetMethodId ||
376f4a9311fa018c78a7b30a73bd8ebbaa33c701ae4Casey Dahlin                    item->GetId() > kMaxUserSetMethodId) {
377dff80e51334ba15850f21189f47665d2fc846b68Casey Dahlin                fprintf(stderr, "%s:%d Found out of bounds id (%d) for method: %s\n",
378f4a9311fa018c78a7b30a73bd8ebbaa33c701ae4Casey Dahlin                        filename, item->GetLine(),
379f4a9311fa018c78a7b30a73bd8ebbaa33c701ae4Casey Dahlin                        item->GetId(), item->GetName().c_str());
380dff80e51334ba15850f21189f47665d2fc846b68Casey Dahlin                fprintf(stderr, "    Value for id must be between %d and %d inclusive.\n",
381dff80e51334ba15850f21189f47665d2fc846b68Casey Dahlin                        kMinUserSetMethodId, kMaxUserSetMethodId);
382ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski                return 1;
383ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski            }
384f4a9311fa018c78a7b30a73bd8ebbaa33c701ae4Casey Dahlin            usedIds.insert(item->GetId());
385dff80e51334ba15850f21189f47665d2fc846b68Casey Dahlin        } else {
386dff80e51334ba15850f21189f47665d2fc846b68Casey Dahlin            hasUnassignedIds = true;
387dff80e51334ba15850f21189f47665d2fc846b68Casey Dahlin        }
388dff80e51334ba15850f21189f47665d2fc846b68Casey Dahlin        if (hasAssignedIds && hasUnassignedIds) {
389dff80e51334ba15850f21189f47665d2fc846b68Casey Dahlin            fprintf(stderr,
390dff80e51334ba15850f21189f47665d2fc846b68Casey Dahlin                    "%s: You must either assign id's to all methods or to none of them.\n",
391dff80e51334ba15850f21189f47665d2fc846b68Casey Dahlin                    filename);
392dff80e51334ba15850f21189f47665d2fc846b68Casey Dahlin            return 1;
393ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski        }
394ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski    }
395ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski
396ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski    // In the case that all methods have unassigned id's, set a unique id for them.
397ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski    if (hasUnassignedIds) {
398ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski        int newId = 0;
3995c69deb2a90d487d7b57618eb07a34c85c8112e7Casey Dahlin        for (const auto& item : items) {
400f4a9311fa018c78a7b30a73bd8ebbaa33c701ae4Casey Dahlin            item->SetId(newId++);
401ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski        }
402ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski    }
403ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski
404ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski    // success
405ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski    return 0;
406ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski}
407ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski
408ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley// TODO: Remove this in favor of using the YACC parser b/25479378
409ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wileybool ParsePreprocessedLine(const string& line, string* decl,
410ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley                           vector<string>* package, string* class_name) {
411ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley  // erase all trailing whitespace and semicolons
412ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley  const size_t end = line.find_last_not_of(" ;\t");
413ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley  if (end == string::npos) {
414ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley    return false;
415ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley  }
416ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley  if (line.rfind(';', end) != string::npos) {
417ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley    return false;
418ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley  }
419ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley
420ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley  decl->clear();
421ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley  string type;
422ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley  vector<string> pieces = Split(line.substr(0, end + 1), " \t");
423ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley  for (const string& piece : pieces) {
424ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley    if (piece.empty()) {
425ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley      continue;
426ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley    }
427ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley    if (decl->empty()) {
428ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley      *decl = std::move(piece);
429ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley    } else if (type.empty()) {
430ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley      type = std::move(piece);
431ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley    } else {
432ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley      return false;
433ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley    }
434ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley  }
435ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley
436ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley  // Note that this logic is absolutely wrong.  Given a parcelable
437ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley  // org.some.Foo.Bar, the class name is Foo.Bar, but this code will claim that
438ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley  // the class is just Bar.  However, this was the way it was done in the past.
439ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley  //
440ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley  // See b/17415692
441ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley  size_t dot_pos = type.rfind('.');
442ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley  if (dot_pos != string::npos) {
443ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley    *class_name = type.substr(dot_pos + 1);
444ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley    *package = Split(type.substr(0, dot_pos), ".");
445ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley  } else {
446ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley    *class_name = type;
447ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley    package->clear();
448ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley  }
449ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley
450ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley  return true;
451ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley}
452ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley
4534a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley}  // namespace
4544a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley
4554a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wileynamespace internals {
4564a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley
457ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wileybool parse_preprocessed_file(const IoDelegate& io_delegate,
458ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley                             const string& filename, TypeNamespace* types) {
459ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley  bool success = true;
460ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley  unique_ptr<LineReader> line_reader = io_delegate.GetLineReader(filename);
461ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley  if (!line_reader) {
462ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley    LOG(ERROR) << "cannot open preprocessed file: " << filename;
463ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley    success = false;
464ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley    return success;
465ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley  }
466ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley
467ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley  string line;
468ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley  unsigned lineno = 1;
469ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley  for ( ; line_reader->ReadLine(&line); ++lineno) {
470ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley    if (line.empty() || line.compare(0, 2, "//") == 0) {
471ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley      // skip comments and empty lines
472ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley      continue;
473ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley    }
474ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley
475ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley    string decl;
476ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley    vector<string> package;
477ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley    string class_name;
478ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley    if (!ParsePreprocessedLine(line, &decl, &package, &class_name)) {
479ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley      success = false;
480ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley      break;
481ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley    }
482ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley
483ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley    if (decl == "parcelable") {
4848aa4d9f32dcfb37011d41417814c01bd2d7a473bChristopher Wiley      AidlParcelable doc(new AidlQualifiedName(class_name, ""),
4858aa4d9f32dcfb37011d41417814c01bd2d7a473bChristopher Wiley                         lineno, package);
486c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlin      types->AddParcelableType(doc, filename);
487ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley    } else if (decl == "interface") {
488d40e2fed2c19850d53f1620322ac5cbca2c0e245Casey Dahlin      auto temp = new std::vector<std::unique_ptr<AidlMember>>();
489ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley      AidlInterface doc(class_name, lineno, "", false, temp, package);
490c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlin      types->AddBinderType(doc, filename);
491ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley    } else {
492ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley      success = false;
493ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley      break;
494ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley    }
495ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley  }
496ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley  if (!success) {
497ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley    LOG(ERROR) << filename << ':' << lineno
498ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley               << " malformed preprocessed file line: '" << line << "'";
499ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley  }
500ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley
501ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley  return success;
502ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley}
503ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley
504632801d891bd269badc780ab5f0f08e56e6df10aChristopher WileyAidlError load_and_validate_aidl(
505632801d891bd269badc780ab5f0f08e56e6df10aChristopher Wiley    const std::vector<std::string> preprocessed_files,
506632801d891bd269badc780ab5f0f08e56e6df10aChristopher Wiley    const std::vector<std::string> import_paths,
507632801d891bd269badc780ab5f0f08e56e6df10aChristopher Wiley    const std::string& input_file_name,
508632801d891bd269badc780ab5f0f08e56e6df10aChristopher Wiley    const IoDelegate& io_delegate,
509632801d891bd269badc780ab5f0f08e56e6df10aChristopher Wiley    TypeNamespace* types,
510632801d891bd269badc780ab5f0f08e56e6df10aChristopher Wiley    std::unique_ptr<AidlInterface>* returned_interface,
511632801d891bd269badc780ab5f0f08e56e6df10aChristopher Wiley    std::vector<std::unique_ptr<AidlImport>>* returned_imports) {
512632801d891bd269badc780ab5f0f08e56e6df10aChristopher Wiley  AidlError err = AidlError::OK;
513ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski
514c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlin  std::map<AidlImport*,std::unique_ptr<AidlDocument>> docs;
515624358c0681569748611c9d02186ab402e175798Casey Dahlin
5163a9d1581bd54255fbfcbc09b852b4b78d32d0a6dChristopher Wiley  // import the preprocessed file
517eb1acc1cf7dbf578d8ab2e596982c4c635aa9865Christopher Wiley  for (const string& s : preprocessed_files) {
518ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley    if (!parse_preprocessed_file(io_delegate, s, types)) {
519632801d891bd269badc780ab5f0f08e56e6df10aChristopher Wiley      err = AidlError::BAD_PRE_PROCESSED_FILE;
520ef1409302aa97b1807e55c63588ac0a428f41a06Christopher Wiley    }
5213a9d1581bd54255fbfcbc09b852b4b78d32d0a6dChristopher Wiley  }
522632801d891bd269badc780ab5f0f08e56e6df10aChristopher Wiley  if (err != AidlError::OK) {
5233a9d1581bd54255fbfcbc09b852b4b78d32d0a6dChristopher Wiley    return err;
5243a9d1581bd54255fbfcbc09b852b4b78d32d0a6dChristopher Wiley  }
5253a9d1581bd54255fbfcbc09b852b4b78d32d0a6dChristopher Wiley
526c16e5e70c0d570839f41c49a900035c5c82ecd95Christopher Wiley  // parse the input file
5274a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley  Parser p{io_delegate};
5284a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley  if (!p.ParseFile(input_file_name)) {
529632801d891bd269badc780ab5f0f08e56e6df10aChristopher Wiley    return AidlError::PARSE_ERROR;
5304a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley  }
5312cc93169679e222dda71c73814f28a9fb0832166Casey Dahlin
532c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlin  AidlDocument* parsed_doc = p.GetDocument();
533c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlin
534c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlin  unique_ptr<AidlInterface> interface(parsed_doc->ReleaseInterface());
535c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlin
536c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlin  if (!interface) {
537e60d99ca384141694bca8095eebb47640b6fe12aChristopher Wiley    LOG(ERROR) << "refusing to generate code from aidl file defining "
538e60d99ca384141694bca8095eebb47640b6fe12aChristopher Wiley                  "parcelable";
539632801d891bd269badc780ab5f0f08e56e6df10aChristopher Wiley    return AidlError::FOUND_PARCELABLE;
540632801d891bd269badc780ab5f0f08e56e6df10aChristopher Wiley  }
541632801d891bd269badc780ab5f0f08e56e6df10aChristopher Wiley
54242727f851672ff8f3099db81fa21c969e553e150Casey Dahlin  if (!check_filename(input_file_name.c_str(), interface->GetPackage(),
543632801d891bd269badc780ab5f0f08e56e6df10aChristopher Wiley                      interface->GetName(), interface->GetLine()) ||
544632801d891bd269badc780ab5f0f08e56e6df10aChristopher Wiley      !types->IsValidPackage(interface->GetPackage())) {
545632801d891bd269badc780ab5f0f08e56e6df10aChristopher Wiley    LOG(ERROR) << "Invalid package declaration '" << interface->GetPackage()
546632801d891bd269badc780ab5f0f08e56e6df10aChristopher Wiley               << "'";
547632801d891bd269badc780ab5f0f08e56e6df10aChristopher Wiley    return AidlError::BAD_PACKAGE;
548632801d891bd269badc780ab5f0f08e56e6df10aChristopher Wiley  }
549c16e5e70c0d570839f41c49a900035c5c82ecd95Christopher Wiley
550c16e5e70c0d570839f41c49a900035c5c82ecd95Christopher Wiley  // parse the imports of the input file
55172877acd3b57462fcd452bff4a9d7ff936936a8eChristopher Wiley  ImportResolver import_resolver{io_delegate, import_paths};
5520edf34239909bbc16e884ea2517e5f3398185d0fCasey Dahlin  for (auto& import : p.GetImports()) {
553934a82d1b045a5944d115dece4cf01f539103c11Christopher Wiley    if (types->HasImportType(*import)) {
554fb4b22dfbe0f87aaad492dc8a25201179c235baeChristopher Wiley      // There are places in the Android tree where an import doesn't resolve,
555fb4b22dfbe0f87aaad492dc8a25201179c235baeChristopher Wiley      // but we'll pick the type up through the preprocessed types.
556fb4b22dfbe0f87aaad492dc8a25201179c235baeChristopher Wiley      // This seems like an error, but legacy support demands we support it...
557c16e5e70c0d570839f41c49a900035c5c82ecd95Christopher Wiley      continue;
558c16e5e70c0d570839f41c49a900035c5c82ecd95Christopher Wiley    }
5590edf34239909bbc16e884ea2517e5f3398185d0fCasey Dahlin    string import_path = import_resolver.FindImportFile(import->GetNeededClass());
56072877acd3b57462fcd452bff4a9d7ff936936a8eChristopher Wiley    if (import_path.empty()) {
5610edf34239909bbc16e884ea2517e5f3398185d0fCasey Dahlin      cerr << import->GetFileFrom() << ":" << import->GetLine()
562c16e5e70c0d570839f41c49a900035c5c82ecd95Christopher Wiley           << ": couldn't find import for class "
5630edf34239909bbc16e884ea2517e5f3398185d0fCasey Dahlin           << import->GetNeededClass() << endl;
564632801d891bd269badc780ab5f0f08e56e6df10aChristopher Wiley      err = AidlError::BAD_IMPORT;
565c16e5e70c0d570839f41c49a900035c5c82ecd95Christopher Wiley      continue;
566c16e5e70c0d570839f41c49a900035c5c82ecd95Christopher Wiley    }
5670edf34239909bbc16e884ea2517e5f3398185d0fCasey Dahlin    import->SetFilename(import_path);
5682cc93169679e222dda71c73814f28a9fb0832166Casey Dahlin
5694a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley    Parser p{io_delegate};
5700edf34239909bbc16e884ea2517e5f3398185d0fCasey Dahlin    if (!p.ParseFile(import->GetFilename())) {
571c16e5e70c0d570839f41c49a900035c5c82ecd95Christopher Wiley      cerr << "error while parsing import for class "
5720edf34239909bbc16e884ea2517e5f3398185d0fCasey Dahlin           << import->GetNeededClass() << endl;
573632801d891bd269badc780ab5f0f08e56e6df10aChristopher Wiley      err = AidlError::BAD_IMPORT;
574c16e5e70c0d570839f41c49a900035c5c82ecd95Christopher Wiley      continue;
575c16e5e70c0d570839f41c49a900035c5c82ecd95Christopher Wiley    }
5764a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley
577c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlin    std::unique_ptr<AidlDocument> document(p.ReleaseDocument());
578c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlin    if (!check_filenames(import->GetFilename(), document.get()))
579632801d891bd269badc780ab5f0f08e56e6df10aChristopher Wiley      err = AidlError::BAD_IMPORT;
580c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlin    docs[import.get()] = std::move(document);
581c16e5e70c0d570839f41c49a900035c5c82ecd95Christopher Wiley  }
582632801d891bd269badc780ab5f0f08e56e6df10aChristopher Wiley  if (err != AidlError::OK) {
583c16e5e70c0d570839f41c49a900035c5c82ecd95Christopher Wiley    return err;
5843a9d1581bd54255fbfcbc09b852b4b78d32d0a6dChristopher Wiley  }
5853a9d1581bd54255fbfcbc09b852b4b78d32d0a6dChristopher Wiley
5863a9d1581bd54255fbfcbc09b852b4b78d32d0a6dChristopher Wiley  // gather the types that have been declared
587c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlin  if (!types->AddBinderType(*interface.get(), input_file_name)) {
588632801d891bd269badc780ab5f0f08e56e6df10aChristopher Wiley    err = AidlError::BAD_TYPE;
58984c1eacc7f09377d7724f0783187b0477fe7c2baChristopher Wiley  }
590c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlin
591934a82d1b045a5944d115dece4cf01f539103c11Christopher Wiley  interface->SetLanguageType(types->GetInterfaceType(*interface));
592a2f77c40fb6287895e2030055c0104eac0a1f73aCasey Dahlin
5930edf34239909bbc16e884ea2517e5f3398185d0fCasey Dahlin  for (const auto& import : p.GetImports()) {
594c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlin    // If we skipped an unresolved import above (see comment there) we'll have
595c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlin    // an empty bucket here.
596c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlin    const auto import_itr = docs.find(import.get());
597c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlin    if (import_itr == docs.cend()) {
598c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlin      continue;
599c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlin    }
600c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlin
601c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlin    if (!gather_types(import->GetFilename(), import_itr->second.get(), types)) {
602632801d891bd269badc780ab5f0f08e56e6df10aChristopher Wiley      err = AidlError::BAD_TYPE;
60384c1eacc7f09377d7724f0783187b0477fe7c2baChristopher Wiley    }
6043a9d1581bd54255fbfcbc09b852b4b78d32d0a6dChristopher Wiley  }
6053a9d1581bd54255fbfcbc09b852b4b78d32d0a6dChristopher Wiley
606c16e5e70c0d570839f41c49a900035c5c82ecd95Christopher Wiley  // check the referenced types in parsed_doc to make sure we've imported them
607632801d891bd269badc780ab5f0f08e56e6df10aChristopher Wiley  if (check_types(input_file_name, interface.get(), types) != 0) {
608632801d891bd269badc780ab5f0f08e56e6df10aChristopher Wiley    err = AidlError::BAD_TYPE;
609632801d891bd269badc780ab5f0f08e56e6df10aChristopher Wiley  }
610632801d891bd269badc780ab5f0f08e56e6df10aChristopher Wiley  if (err != AidlError::OK) {
611632801d891bd269badc780ab5f0f08e56e6df10aChristopher Wiley    return err;
612632801d891bd269badc780ab5f0f08e56e6df10aChristopher Wiley  }
613c16e5e70c0d570839f41c49a900035c5c82ecd95Christopher Wiley
614c16e5e70c0d570839f41c49a900035c5c82ecd95Christopher Wiley
615c16e5e70c0d570839f41c49a900035c5c82ecd95Christopher Wiley  // assign method ids and validate.
616632801d891bd269badc780ab5f0f08e56e6df10aChristopher Wiley  if (check_and_assign_method_ids(input_file_name.c_str(),
617632801d891bd269badc780ab5f0f08e56e6df10aChristopher Wiley                                  interface->GetMethods()) != 0) {
618632801d891bd269badc780ab5f0f08e56e6df10aChristopher Wiley    return AidlError::BAD_METHOD_ID;
6193a9d1581bd54255fbfcbc09b852b4b78d32d0a6dChristopher Wiley  }
6203a9d1581bd54255fbfcbc09b852b4b78d32d0a6dChristopher Wiley
6210edf34239909bbc16e884ea2517e5f3398185d0fCasey Dahlin  if (returned_interface)
62290be4e3fe6d16ea8e8263b80989ef2ab4e6ef9c6Christopher Wiley    *returned_interface = std::move(interface);
6230edf34239909bbc16e884ea2517e5f3398185d0fCasey Dahlin
6240edf34239909bbc16e884ea2517e5f3398185d0fCasey Dahlin  if (returned_imports)
6250edf34239909bbc16e884ea2517e5f3398185d0fCasey Dahlin    p.ReleaseImports(returned_imports);
6260edf34239909bbc16e884ea2517e5f3398185d0fCasey Dahlin
627632801d891bd269badc780ab5f0f08e56e6df10aChristopher Wiley  return AidlError::OK;
628eb1acc1cf7dbf578d8ab2e596982c4c635aa9865Christopher Wiley}
629eb1acc1cf7dbf578d8ab2e596982c4c635aa9865Christopher Wiley
6302cc93169679e222dda71c73814f28a9fb0832166Casey Dahlin} // namespace internals
6312cc93169679e222dda71c73814f28a9fb0832166Casey Dahlin
6324a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wileyint compile_aidl_to_cpp(const CppOptions& options,
6334a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley                        const IoDelegate& io_delegate) {
63490be4e3fe6d16ea8e8263b80989ef2ab4e6ef9c6Christopher Wiley  unique_ptr<AidlInterface> interface;
6350edf34239909bbc16e884ea2517e5f3398185d0fCasey Dahlin  std::vector<std::unique_ptr<AidlImport>> imports;
636e3550c6679939d2bf5f35c540cd83198ab156fb7Christopher Wiley  unique_ptr<cpp::TypeNamespace> types(new cpp::TypeNamespace());
6375679952c38925a54b75b087068887002e57f3174Christopher Wiley  types->Init();
638632801d891bd269badc780ab5f0f08e56e6df10aChristopher Wiley  AidlError err = internals::load_and_validate_aidl(
6394a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley      std::vector<std::string>{},  // no preprocessed files
6404a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley      options.ImportPaths(),
6414a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley      options.InputFileName(),
6424a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley      io_delegate,
6434a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley      types.get(),
6444a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley      &interface,
6454a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley      &imports);
646632801d891bd269badc780ab5f0f08e56e6df10aChristopher Wiley  if (err != AidlError::OK) {
647632801d891bd269badc780ab5f0f08e56e6df10aChristopher Wiley    return 1;
648eb1acc1cf7dbf578d8ab2e596982c4c635aa9865Christopher Wiley  }
649eb1acc1cf7dbf578d8ab2e596982c4c635aa9865Christopher Wiley
6503a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley  if (!write_cpp_dep_file(options, *interface, imports, io_delegate)) {
6513a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley    return 1;
65219059cb70c5330787ba88f3860444e6da3ef3ca0Christopher Wiley  }
653eb1acc1cf7dbf578d8ab2e596982c4c635aa9865Christopher Wiley
654054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley  return (cpp::GenerateCpp(options, *types, *interface, io_delegate)) ? 0 : 1;
655eb1acc1cf7dbf578d8ab2e596982c4c635aa9865Christopher Wiley}
656eb1acc1cf7dbf578d8ab2e596982c4c635aa9865Christopher Wiley
6574a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wileyint compile_aidl_to_java(const JavaOptions& options,
6584a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley                         const IoDelegate& io_delegate) {
65990be4e3fe6d16ea8e8263b80989ef2ab4e6ef9c6Christopher Wiley  unique_ptr<AidlInterface> interface;
6600edf34239909bbc16e884ea2517e5f3398185d0fCasey Dahlin  std::vector<std::unique_ptr<AidlImport>> imports;
661db154a5f543ff697248df649a14f2ac4a70cbf0eChristopher Wiley  unique_ptr<java::JavaTypeNamespace> types(new java::JavaTypeNamespace());
6625679952c38925a54b75b087068887002e57f3174Christopher Wiley  types->Init();
663632801d891bd269badc780ab5f0f08e56e6df10aChristopher Wiley  AidlError aidl_err = internals::load_and_validate_aidl(
6644a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley      options.preprocessed_files_,
6654a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley      options.import_paths_,
6664a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley      options.input_file_name_,
6674a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley      io_delegate,
6684a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley      types.get(),
6694a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley      &interface,
6704a2884b0e9414ed9dfee4e141e8bd462c07b442bChristopher Wiley      &imports);
671632801d891bd269badc780ab5f0f08e56e6df10aChristopher Wiley  if (aidl_err == AidlError::FOUND_PARCELABLE && !options.fail_on_parcelable_) {
672632801d891bd269badc780ab5f0f08e56e6df10aChristopher Wiley    // We aborted code generation because this file contains parcelables.
673632801d891bd269badc780ab5f0f08e56e6df10aChristopher Wiley    // However, we were not told to complain if we find parcelables.
674303b43ca5a93ce89f438ad4dd200c0ca317832deChristopher Wiley    // Just generate a dep file and exit quietly.  The dep file is for a legacy
675303b43ca5a93ce89f438ad4dd200c0ca317832deChristopher Wiley    // use case by the SDK.
676303b43ca5a93ce89f438ad4dd200c0ca317832deChristopher Wiley    write_java_dep_file(options, imports, io_delegate, "");
677632801d891bd269badc780ab5f0f08e56e6df10aChristopher Wiley    return 0;
678632801d891bd269badc780ab5f0f08e56e6df10aChristopher Wiley  }
679632801d891bd269badc780ab5f0f08e56e6df10aChristopher Wiley  if (aidl_err != AidlError::OK) {
680632801d891bd269badc780ab5f0f08e56e6df10aChristopher Wiley    return 1;
681eb1acc1cf7dbf578d8ab2e596982c4c635aa9865Christopher Wiley  }
682eb1acc1cf7dbf578d8ab2e596982c4c635aa9865Christopher Wiley
6833a9d1581bd54255fbfcbc09b852b4b78d32d0a6dChristopher Wiley  string output_file_name = options.output_file_name_;
6843a9d1581bd54255fbfcbc09b852b4b78d32d0a6dChristopher Wiley  // if needed, generate the output file name from the base folder
685632801d891bd269badc780ab5f0f08e56e6df10aChristopher Wiley  if (output_file_name.empty() && !options.output_base_folder_.empty()) {
68690be4e3fe6d16ea8e8263b80989ef2ab4e6ef9c6Christopher Wiley    output_file_name = generate_outputFileName(options, *interface);
6873a9d1581bd54255fbfcbc09b852b4b78d32d0a6dChristopher Wiley  }
6883a9d1581bd54255fbfcbc09b852b4b78d32d0a6dChristopher Wiley
6896453351b3ee9ce9b91650a8175464a6e339130c7Casey Dahlin  // make sure the folders of the output file all exists
6906453351b3ee9ce9b91650a8175464a6e339130c7Casey Dahlin  if (!io_delegate.CreatePathForFile(output_file_name)) {
6916453351b3ee9ce9b91650a8175464a6e339130c7Casey Dahlin    return 1;
6926453351b3ee9ce9b91650a8175464a6e339130c7Casey Dahlin  }
6936453351b3ee9ce9b91650a8175464a6e339130c7Casey Dahlin
6948f314b0d4c3f195c98c6dd7e671fc2b9d4bfa76fChristopher Wiley  if (!write_java_dep_file(options, imports, io_delegate, output_file_name)) {
6953a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley    return 1;
6963a9d1581bd54255fbfcbc09b852b4b78d32d0a6dChristopher Wiley  }
697ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski
698632801d891bd269badc780ab5f0f08e56e6df10aChristopher Wiley  return generate_java(output_file_name, options.input_file_name_.c_str(),
699632801d891bd269badc780ab5f0f08e56e6df10aChristopher Wiley                       interface.get(), types.get(), io_delegate);
700ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski}
701ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski
702c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlinbool preprocess_aidl(const JavaOptions& options,
703c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlin                     const IoDelegate& io_delegate) {
704c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlin  unique_ptr<CodeWriter> writer =
705c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlin      io_delegate.GetCodeWriter(options.output_file_name_);
706b696437d842d59c0cc26411fa3d71cb91897c572Casey Dahlin
707c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlin  for (const auto& file : options.files_to_preprocess_) {
708c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlin    Parser p{io_delegate};
709c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlin    if (!p.ParseFile(file))
710c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlin      return false;
711c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlin    AidlDocument* doc = p.GetDocument();
712c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlin    string line;
713c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlin
714c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlin    const AidlInterface* interface = doc->GetInterface();
715c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlin
716c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlin    if (interface != nullptr &&
717c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlin        !writer->Write("interface %s;\n",
718c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlin                       interface->GetCanonicalName().c_str())) {
719c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlin      return false;
720ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski    }
721ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski
722c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlin    for (const auto& parcelable : doc->GetParcelables()) {
723c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlin      if (!writer->Write("parcelable %s;\n",
724c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlin                         parcelable->GetCanonicalName().c_str())) {
725c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlin        return false;
726c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlin      }
727ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski    }
728c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlin  }
729ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski
730c1f39b4ea30e7313eeb7f3d3fd5ec66ba00f2bb5Casey Dahlin  return writer->Close();
731ffa1686a7a8964d1f6e08ee2ab3e5eb42eb5f0b3Adam Lesinski}
732fdeb0f4b96b6c39b1b9ed3358634f180f9e6df06Christopher Wiley
733fdeb0f4b96b6c39b1b9ed3358634f180f9e6df06Christopher Wiley}  // namespace android
734fdeb0f4b96b6c39b1b9ed3358634f180f9e6df06Christopher Wiley}  // namespace aidl
735